fix UI threading bugs
authorAndrew Lorimer <andrew@lorimer.id.au>
Sat, 22 May 2021 07:59:15 +0000 (17:59 +1000)
committerAndrew Lorimer <andrew@lorimer.id.au>
Sat, 22 May 2021 07:59:15 +0000 (17:59 +1000)
ppt_control/ppt_control.py
index 8537f81af4f3ce20ab5961a6775f2de28fc3dee5..1f4cfde85895063ba2d14b65f3b838fba9fa0760 100755 (executable)
@@ -32,6 +32,7 @@ global STATE
 global STATE_DEFAULT\r
 global current_slideshow\r
 global interface_root\r
 global STATE_DEFAULT\r
 global current_slideshow\r
 global interface_root\r
+global interface_thread\r
 global logger\r
 global refresh_daemon\r
 global status_label\r
 global logger\r
 global refresh_daemon\r
 global status_label\r
@@ -43,6 +44,7 @@ global icon
 scheduler = None\r
 current_slideshow = None\r
 interface_root = None\r
 scheduler = None\r
 current_slideshow = None\r
 interface_root = None\r
+interface_thread = None\r
 CONFIG_FILE = r'''..\ppt-control.ini'''\r
 LOGFILE = r'''..\ppt-control.log'''\r
 logger = None\r
 CONFIG_FILE = r'''..\ppt-control.ini'''\r
 LOGFILE = r'''..\ppt-control.log'''\r
 logger = None\r
@@ -262,7 +264,6 @@ class Slideshow:
 \r
     def unload(self):\r
         connect_ppt()\r
 \r
     def unload(self):\r
         connect_ppt()\r
-        reset_ppt_button.config(state = tk.DISABLED)\r
 \r
     def refresh(self):\r
         try:\r
 \r
     def refresh(self):\r
         try:\r
@@ -428,12 +429,14 @@ def refresh_interval():
         time.sleep(0.5)\r
 \r
 def refresh_status():\r
         time.sleep(0.5)\r
 \r
 def refresh_status():\r
-    if status_label is not None:\r
-        status_label.config(text="PowerPoint status: " + ("not " if not STATE["connected"] else "") +  "connected")\r
-        http_label.config(text="HTTP server: " + ("not " if http_server is None else "") +  "running")\r
-        #ws_label.config(text="WebSocket server: " + ("not " if ws_daemon is not None or not ws_daemon.is_alive() else "") +  "running")\r
-    if reset_ppt_button is not None:\r
-        reset_ppt_button.config(state = tk.DISABLED if not STATE["connected"] else tk.NORMAL)\r
+    if interface_root is not None and interface_root.state == "normal":\r
+        if status_label is not None:\r
+            status_label.config(text="PowerPoint status: " + ("not " if not STATE["connected"] else "") +  "connected")\r
+        if http_label is not None:\r
+            http_label.config(text="HTTP server: " + ("not " if http_server is None else "") +  "running")\r
+            #ws_label.config(text="WebSocket server: " + ("not " if ws_daemon is not None or not ws_daemon.is_alive() else "") +  "running")\r
+        if reset_ppt_button is not None:\r
+            reset_ppt_button.config(state = tk.DISABLED if not STATE["connected"] else tk.NORMAL)\r
 \r
 def connect_ppt():\r
     global STATE\r
 \r
 def connect_ppt():\r
     global STATE\r
@@ -441,6 +444,8 @@ def connect_ppt():
     if STATE["connected"] == 1:\r
         logger.info("Disconnected from PowerPoint instance")\r
         icon.notify("Disconnected from PowerPoint instance")\r
     if STATE["connected"] == 1:\r
         logger.info("Disconnected from PowerPoint instance")\r
         icon.notify("Disconnected from PowerPoint instance")\r
+        if reset_ppt_button is not None:\r
+            reset_ppt_button.config(state = tk.DISABLED)\r
         refresh_daemon.do_run = False\r
         STATE = copy(STATE_DEFAULT)\r
         if icon is not None:\r
         refresh_daemon.do_run = False\r
         STATE = copy(STATE_DEFAULT)\r
         if icon is not None:\r
@@ -478,13 +483,19 @@ def on_closing():
     global status_label\r
     global http_label\r
     global ws_label\r
     global status_label\r
     global http_label\r
     global ws_label\r
+    global interface_thread\r
     status_label = None\r
     http_label = None\r
     ws_label = None\r
     status_label = None\r
     http_label = None\r
     ws_label = None\r
+    logger.debug("Destroying interface root")\r
     interface_root.destroy()\r
     interface_root.destroy()\r
+    logger.debug("Destroying interface thread")\r
+    interface_thread.root.quit()\r
+    interface_thread = None\r
     \r
 def open_settings(_=None):\r
     global interface_root\r
     \r
 def open_settings(_=None):\r
     global interface_root\r
+    global interface_thread\r
     interface_root = tk.Tk()\r
     interface_root.protocol("WM_DELETE_WINDOW", on_closing)\r
     interface_root.iconphoto(False, tk.PhotoImage(file=os.path.dirname(os.path.realpath(__file__)) + r'''\static\icons\ppt.png'''))\r
     interface_root = tk.Tk()\r
     interface_root.protocol("WM_DELETE_WINDOW", on_closing)\r
     interface_root.iconphoto(False, tk.PhotoImage(file=os.path.dirname(os.path.realpath(__file__)) + r'''\static\icons\ppt.png'''))\r