pygui updated progress tasks to be self contained and leverage a title value to display runtime with more context to user

This commit is contained in:
Blake Harnden 2020-05-03 21:47:58 -07:00
parent 1dd45f4424
commit 4ec6ef25fe
5 changed files with 40 additions and 30 deletions

View file

@ -1,6 +1,5 @@
import logging import logging
import math import math
import time
import tkinter as tk import tkinter as tk
from tkinter import font, ttk from tkinter import font, ttk
from tkinter.ttk import Progressbar from tkinter.ttk import Progressbar
@ -15,7 +14,6 @@ from core.gui.images import ImageEnum, Images
from core.gui.menubar import Menubar from core.gui.menubar import Menubar
from core.gui.nodeutils import NodeUtils from core.gui.nodeutils import NodeUtils
from core.gui.statusbar import StatusBar from core.gui.statusbar import StatusBar
from core.gui.task import ProgressTask
from core.gui.toolbar import Toolbar from core.gui.toolbar import Toolbar
from core.gui.validation import InputValidation from core.gui.validation import InputValidation
@ -37,7 +35,6 @@ class Application(ttk.Frame):
self.statusbar = None self.statusbar = None
self.validation = None self.validation = None
self.progress = None self.progress = None
self.time = None
# fonts # fonts
self.fonts_size = None self.fonts_size = None
@ -127,21 +124,6 @@ class Application(ttk.Frame):
self.statusbar = StatusBar(self.right_frame, self) self.statusbar = StatusBar(self.right_frame, self)
self.statusbar.grid(sticky="ew") self.statusbar.grid(sticky="ew")
def progress_task(self, task: ProgressTask) -> None:
self.progress.grid(sticky="ew")
self.progress.start()
self.time = time.perf_counter()
task.app = self
task.start()
def progress_task_complete(self) -> None:
self.progress.stop()
self.progress.grid_forget()
total = time.perf_counter() - self.time
self.time = None
message = f"Task ran for {total:.3f} seconds"
self.statusbar.set_status(message)
def show_grpc_exception(self, title: str, e: grpc.RpcError) -> None: def show_grpc_exception(self, title: str, e: grpc.RpcError) -> None:
logging.exception("app grpc exception", exc_info=e) logging.exception("app grpc exception", exc_info=e)
message = e.details() message = e.details()

View file

@ -185,8 +185,10 @@ class SessionsDialog(Dialog):
self.destroy() self.destroy()
if self.app.core.xml_file: if self.app.core.xml_file:
self.app.core.xml_file = None self.app.core.xml_file = None
task = ProgressTask(self.app.core.join_session, args=(session_id,)) task = ProgressTask(
self.app.progress_task(task) self.app, "Join", self.app.core.join_session, args=(session_id,)
)
task.start()
def double_click_join(self, _event: tk.Event) -> None: def double_click_join(self, _event: tk.Event) -> None:
item = self.tree.selection() item = self.tree.selection()

View file

@ -340,8 +340,8 @@ class Menubar(tk.Menu):
self.core.xml_file = filename self.core.xml_file = filename
self.core.xml_dir = str(os.path.dirname(filename)) self.core.xml_dir = str(os.path.dirname(filename))
self.prompt_save_running_session() self.prompt_save_running_session()
task = ProgressTask(self.core.open_xml, args=(filename,)) task = ProgressTask(self.app, "Open XML", self.core.open_xml, args=(filename,))
self.app.progress_task(task) task.start()
def execute_python(self): def execute_python(self):
dialog = ExecutePythonDialog(self.app, self.app) dialog = ExecutePythonDialog(self.app, self.app)

View file

@ -1,20 +1,34 @@
import logging import logging
import threading import threading
from typing import Any, Callable, Tuple import time
from typing import TYPE_CHECKING, Any, Callable, Tuple
if TYPE_CHECKING:
from core.gui.app import Application
class ProgressTask: class ProgressTask:
def __init__( def __init__(
self, task: Callable, callback: Callable = None, args: Tuple[Any] = None self,
app: "Application",
title: str,
task: Callable,
callback: Callable = None,
args: Tuple[Any] = None,
): ):
self.app = None self.app = app
self.title = title
self.task = task self.task = task
self.callback = callback self.callback = callback
self.args = args self.args = args
if self.args is None: if self.args is None:
self.args = () self.args = ()
self.time = None
def start(self) -> None: def start(self) -> None:
self.app.progress.grid(sticky="ew")
self.app.progress.start()
self.time = time.perf_counter()
thread = threading.Thread(target=self.run, daemon=True) thread = threading.Thread(target=self.run, daemon=True)
thread.start() thread.start()
@ -33,4 +47,12 @@ class ProgressTask:
logging.exception("progress task exception") logging.exception("progress task exception")
self.app.show_exception("Task Error", e) self.app.show_exception("Task Error", e)
finally: finally:
self.app.after(0, self.app.progress_task_complete) self.app.after(0, self.complete)
def complete(self):
self.app.progress.stop()
self.app.progress.grid_forget()
total = time.perf_counter() - self.time
self.time = None
message = f"{self.title} ran for {total:.3f} seconds"
self.app.statusbar.set_status(message)

View file

@ -262,8 +262,10 @@ class Toolbar(ttk.Frame):
""" """
self.app.menubar.change_menubar_item_state(is_runtime=True) self.app.menubar.change_menubar_item_state(is_runtime=True)
self.app.canvas.mode = GraphMode.SELECT self.app.canvas.mode = GraphMode.SELECT
task = ProgressTask(self.app.core.start_session, self.start_callback) task = ProgressTask(
self.app.progress_task(task) self.app, "Start", self.app.core.start_session, self.start_callback
)
task.start()
def start_callback(self, response: core_pb2.StartSessionResponse): def start_callback(self, response: core_pb2.StartSessionResponse):
if response.result: if response.result:
@ -446,8 +448,10 @@ class Toolbar(ttk.Frame):
""" """
logging.info("clicked stop button") logging.info("clicked stop button")
self.app.menubar.change_menubar_item_state(is_runtime=False) self.app.menubar.change_menubar_item_state(is_runtime=False)
task = ProgressTask(self.app.core.stop_session, self.stop_callback) task = ProgressTask(
self.app.progress_task(task) self.app, "Stop", self.app.core.stop_session, self.stop_callback
)
task.start()
def stop_callback(self, response: core_pb2.StopSessionResponse): def stop_callback(self, response: core_pb2.StopSessionResponse):
self.set_design() self.set_design()