Просмотр исходного кода

Merged jpcgt/flatcam into master

Kamil Sopko 9 лет назад
Родитель
Сommit
23827451e1
2 измененных файлов с 37 добавлено и 13 удалено
  1. 27 6
      FlatCAMApp.py
  2. 10 7
      FlatCAMWorker.py

+ 27 - 6
FlatCAMApp.py

@@ -10,6 +10,8 @@ import os
 import Tkinter
 from PyQt4 import QtCore
 import time  # Just used for debugging. Double check before removing.
+from xml.dom.minidom import parseString as parse_xml_string
+from contextlib import contextmanager
 
 ########################################
 ##      Imports part of FlatCAM       ##
@@ -25,7 +27,7 @@ from FlatCAMDraw import FlatCAMDraw
 from FlatCAMProcess import *
 from MeasurementTool import Measurement
 from DblSidedTool import DblSidedTool
-from xml.dom.minidom import parseString as parse_xml_string
+
 
 ########################################
 ##                App                 ##
@@ -105,6 +107,10 @@ class App(QtCore.QObject):
 
     message = QtCore.pyqtSignal(str, str, str)
 
+    # Emitted when an unhandled exception happens
+    # in the worker task.
+    thread_exception = QtCore.pyqtSignal(object)
+
     def __init__(self, user_defaults=True, post_gui=None):
         """
         Starts the application.
@@ -2137,13 +2143,22 @@ class App(QtCore.QObject):
 
             return a, kwa
 
-        from contextlib import contextmanager
         @contextmanager
         def wait_signal(signal, timeout=10000):
-            """Block loop until signal emitted, or timeout (ms) elapses."""
+            """
+            Block loop until signal emitted, timeout (ms) elapses
+            or unhandled exception happens in a thread.
+
+            :param signal: Signal to wait for.
+            """
             loop = QtCore.QEventLoop()
+
+            # Normal termination
             signal.connect(loop.quit)
 
+            # Termination by exception in thread
+            self.thread_exception.connect(loop.quit)
+
             status = {'timed_out': False}
 
             def report_quit():
@@ -2152,17 +2167,23 @@ class App(QtCore.QObject):
 
             yield
 
+            # Temporarily change how exceptions are managed.
             oeh = sys.excepthook
             ex = []
-            def exceptHook(type_, value, traceback):
+
+            def except_hook(type_, value, traceback_):
                 ex.append(value)
-                oeh(type_, value, traceback)
-            sys.excepthook = exceptHook
+                oeh(type_, value, traceback_)
+            sys.excepthook = except_hook
 
+            # Terminate on timeout
             if timeout is not None:
                 QtCore.QTimer.singleShot(timeout, report_quit)
 
+            #### Block ####
             loop.exec_()
+
+            # Restore exception management
             sys.excepthook = oeh
             if ex:
                 self.raiseTclError(str(ex[0]))

+ 10 - 7
FlatCAMWorker.py

@@ -14,24 +14,27 @@ class Worker(QtCore.QObject):
         self.name = name
 
     def run(self):
-        # FlatCAMApp.App.log.debug("Worker Started!")
+
         self.app.log.debug("Worker Started!")
 
         # Tasks are queued in the event listener.
         self.app.worker_task.connect(self.do_worker_task)
 
     def do_worker_task(self, task):
-        # FlatCAMApp.App.log.debug("Running task: %s" % str(task))
+
         self.app.log.debug("Running task: %s" % str(task))
 
         # 'worker_name' property of task allows to target
         # specific worker.
-        if 'worker_name' in task and task['worker_name'] == self.name:
-            task['fcn'](*task['params'])
-            return
+        if ('worker_name' in task and task['worker_name'] == self.name) or \
+                ('worker_name' not in task and self.name is None):
+
+            try:
+                task['fcn'](*task['params'])
+            except Exception as e:
+                self.app.thread_exception.emit(e)
+                raise e
 
-        if 'worker_name' not in task and self.name is None:
-            task['fcn'](*task['params'])
             return
 
         # FlatCAMApp.App.log.debug("Task ignored.")