From f14d7ace01e49613195cb4643ea588abb89bf71a Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Wed, 6 Sep 2023 15:55:18 +1000 Subject: [PATCH] logger window reappears --- countess/core/pipeline.py | 4 +-- countess/gui/logger.py | 5 +-- countess/gui/main.py | 65 +++++++++++++++++++++++---------------- 3 files changed, 41 insertions(+), 33 deletions(-) diff --git a/countess/core/pipeline.py b/countess/core/pipeline.py index 1cdb10d..fe0f7bd 100644 --- a/countess/core/pipeline.py +++ b/countess/core/pipeline.py @@ -122,13 +122,13 @@ def prerun(self, logger: Logger, row_limit=PRERUN_ROW_LIMIT): assert isinstance(logger, Logger) if self.is_dirty and self.plugin: - logger.info(f"Prerun {self.name} Start") + logger.progress("Start") for parent_node in self.parent_nodes: parent_node.prerun(logger, row_limit) self.load_config(logger) self.execute(logger, row_limit) self.is_dirty = False - logger.info(f"Prerun {self.name} Done") + logger.progress("Done") def mark_dirty(self): self.is_dirty = True diff --git a/countess/gui/logger.py b/countess/gui/logger.py index 8889fe8..f9eb298 100644 --- a/countess/gui/logger.py +++ b/countess/gui/logger.py @@ -103,13 +103,12 @@ def __init__(self, treeview: ttk.Treeview, progress_frame: tk.Frame, name: str): self.treeview.bind("<>", self.on_click) self.queue: queue.Queue = queue.Queue() - self.on_poll() def on_click(self, event): # XXX display detail more nicely TreeviewDetailWindow(self.detail[self.treeview.focus()]) - def on_poll(self): + def poll(self): # XXX dask apply etc don't seem to be thread safe when updating Tk, so # this adds in a queue to separate the two. try: @@ -136,8 +135,6 @@ def on_poll(self): except queue.Empty: pass - self.treeview.after(1000, self.on_poll) - def log(self, level: str, message: str, detail: Optional[str] = None): print(level, message, detail) self.queue.put((level, message, detail)) diff --git a/countess/gui/main.py b/countess/gui/main.py index 4f3f435..101167a 100644 --- a/countess/gui/main.py +++ b/countess/gui/main.py @@ -1,10 +1,10 @@ import re import sys import tkinter as tk -from tkinter import ttk import webbrowser -from tkinter import filedialog, messagebox +from tkinter import filedialog, messagebox, ttk from typing import Optional +import threading from countess import VERSION from countess.core.config import export_config_graphviz, read_config, write_config @@ -71,10 +71,8 @@ def __init__(self, frame, node, change_callback): self.label.grid(sticky=tk.EW, row=1, padx=10, pady=5) self.label.bind("", self.on_label_configure) - self.logger_subframe = LoggerFrame(self.frame) - self.logger = self.logger_subframe.get_logger(node.name) - self.show_config_subframe() + if self.node.plugin: if self.node.is_dirty: self.config_change_callback() @@ -90,7 +88,9 @@ def show_config_subframe(self): self.config_canvas.grid(row=3, column=0, sticky=tk.NSEW) self.config_scrollbar.grid(row=3, column=1, sticky=tk.NS) - # self.node.prepare(self.logger) + self.logger_subframe = LoggerFrame(self.frame) + self.logger_subframe.grid(row=5, columnspan=2, sticky=tk.NSEW) + self.logger = self.logger_subframe.get_logger(self.node.name) if self.node.plugin: if self.node.notes: @@ -173,12 +173,6 @@ def show_preview_subframe(self): self.preview_subframe.grid(row=4, columnspan=2, sticky=tk.NSEW) - self.logger_subframe.grid(row=5, columnspan=2, sticky=tk.NSEW) - if self.logger.count > 0: - self.logger_subframe.grid(row=5, columnspan=2, sticky=tk.NSEW) - else: - self.logger_subframe.grid_forget() - def name_changed_callback(self, *_): name = self.name_var.get() self.node.name = name @@ -196,23 +190,33 @@ def config_change_callback(self, *_): def config_change_task_callback(self): self.config_change_task = None - self.logger.clear() - self.logger_subframe.grid(row=3, sticky=tk.NSEW) - self.node.prerun(self.logger) - self.show_preview_subframe() + + self.node_update_thread = threading.Thread( + target = self.node.prerun, + args=(self.logger,) + ) + self.node_update_thread.start() + + self.logger_subframe.after(100, self.config_change_task_callback_2) + self.change_callback(self.node) + + def config_change_task_callback_2(self): + self.logger.poll() + + if self.node_update_thread.is_alive(): + self.logger_subframe.after(100, self.config_change_task_callback_2) + return + # XXX stop the form scrolling away when it is refreshed, by putting # it back where it belongs. pos1, pos2 = self.config_scrollbar.get() + self.show_preview_subframe() self.configurator.update() self.frame.update() self.config_canvas.yview_moveto(pos1) self.config_scrollbar.set(pos1, pos2) - self.logger_subframe.after(5000, self.config_change_task_callback_2) - self.change_callback(self.node) - - def config_change_task_callback_2(self): if self.logger.count == 0: self.logger_subframe.grid_forget() else: @@ -278,19 +282,32 @@ def __init__(self, tk_parent: tk.Widget, config_filename: Optional[str] = None): self.frame = tk.Frame(tk_parent) self.frame.grid(sticky=tk.NSEW) + # The left (or top) pane, which contains the pipeline graph self.canvas = FlippyCanvas(self.frame, bg="skyblue") + + # The right (or bottom) pane, which contains everything else. + # 0: The node label + # 1: The plugin description + # 2: Node nodes / add notes button + # 3: Configuration + # 4: Preview pane + # 5: Log output + self.subframe = tk.Frame(self.frame) self.subframe.columnconfigure(0, weight=1) self.subframe.columnconfigure(1, weight=0) self.subframe.rowconfigure(0, weight=0) self.subframe.rowconfigure(1, weight=0) self.subframe.rowconfigure(2, weight=0) - self.subframe.rowconfigure(3, weight=2) + self.subframe.rowconfigure(3, weight=1) self.subframe.rowconfigure(4, weight=1) self.subframe.rowconfigure(5, weight=0) self.frame.bind("", self.on_frame_configure, add=True) + self.logger_subframe = LoggerFrame(self.subframe) + self.logger_subframe.grid(row=5, columnspan=2, sticky=tk.NSEW) + if config_filename: self.config_load(config_filename) else: @@ -398,12 +415,6 @@ def make_root(): root = tk.Tk() # XXX some kind of ttk style setup goes here as a fallback - # Set up treeview font and row heights. - linespace = font.Font(None, 10).metrics()["linespace"] - style = ttk.Style() - style.configure("Treeview", font=(None, 10), rowheight=linespace) - style.configure("Treeview.Heading", font=(None, 10, "bold"), rowheight=linespace) - root.title(f"CountESS {VERSION}") root.rowconfigure(0, weight=0) root.rowconfigure(1, weight=1)