diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 5f9dbff7..75cffb39 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -1393,11 +1393,13 @@ class App(QtCore.QObject): # TODO: Improve the serialization methods and remove this fix. filename = str(filename) - if str(filename) == "": - self.inform.emit("Open cancelled.") - else: - self.worker_task.emit({'fcn': self.open_gerber, - 'params': [filename]}) + self.open_gerber(filename) + + # if str(filename) == "": + # self.inform.emit("Open cancelled.") + # else: + # self.worker_task.emit({'fcn': self.open_gerber, + # 'params': [filename]}) def on_fileopenexcellon(self): """ @@ -1557,14 +1559,10 @@ class App(QtCore.QObject): :return: None """ - App.log.debug("open_gerber()") - - proc = self.proc_container.new("Opening Gerber") - self.progress.emit(10) - # How the object should be initialized def obj_init(gerber_obj, app_obj): assert isinstance(gerber_obj, FlatCAMGerber) + #log.debug("sys.getrefcount(proc) == %d" % sys.getrefcount(proc)) # Opening the file happens here self.progress.emit(30) @@ -1584,6 +1582,14 @@ class App(QtCore.QObject): # Further parsing self.progress.emit(70) # TODO: Note the mixture of self and app_obj used here + App.log.debug("open_gerber()") + + proc = self.proc_container.new("Opening Gerber") + log.debug("sys.getrefcount(proc) == %d" % sys.getrefcount(proc)) + self.progress.emit(10) + + + # Object name name = outname or filename.split('/')[-1].split('\\')[-1] @@ -1608,7 +1614,7 @@ class App(QtCore.QObject): self.file_opened.emit("gerber", filename) self.progress.emit(100) - proc.done() + #proc.done() # GUI feedback self.inform.emit("Opened: " + filename) diff --git a/FlatCAMDraw.py b/FlatCAMDraw.py index 620a402e..5e60dc88 100644 --- a/FlatCAMDraw.py +++ b/FlatCAMDraw.py @@ -442,7 +442,10 @@ class FCSelect(DrawTool): self.start_msg = "Click on geometry to select" def click(self, point): - _, closest_shape = self.storage.nearest(point) + try: + _, closest_shape = self.storage.nearest(point) + except StopIteration: + return "" if self.draw_app.key != 'control': self.draw_app.selected = [] @@ -575,11 +578,14 @@ class FlatCAMDraw(QtCore.QObject): self.app.ui.addToolBar(self.snap_toolbar) ### Event handlers ### - ## Canvas events - self.canvas.mpl_connect('button_press_event', self.on_canvas_click) - self.canvas.mpl_connect('motion_notify_event', self.on_canvas_move) - self.canvas.mpl_connect('key_press_event', self.on_canvas_key) - self.canvas.mpl_connect('key_release_event', self.on_canvas_key_release) + # Connection ids for Matplotlib + self.cid_canvas_click = None + self.cid_canvas_move = None + self.cid_canvas_key = None + self.cid_canvas_key_release = None + + # Connect the canvas + #self.connect_canvas_event_handlers() self.union_btn.triggered.connect(self.union) self.intersection_btn.triggered.connect(self.intersection) @@ -665,6 +671,19 @@ class FlatCAMDraw(QtCore.QObject): def activate(self): pass + def connect_canvas_event_handlers(self): + ## Canvas events + self.cid_canvas_click = self.canvas.mpl_connect('button_press_event', self.on_canvas_click) + self.cid_canvas_move = self.canvas.mpl_connect('motion_notify_event', self.on_canvas_move) + self.cid_canvas_key = self.canvas.mpl_connect('key_press_event', self.on_canvas_key) + self.cid_canvas_key_release = self.canvas.mpl_connect('key_release_event', self.on_canvas_key_release) + + def disconnect_canvas_event_handlers(self): + self.canvas.mpl_disconnect(self.cid_canvas_click) + self.canvas.mpl_disconnect(self.cid_canvas_move) + self.canvas.mpl_disconnect(self.cid_canvas_key) + self.canvas.mpl_disconnect(self.cid_canvas_key_release) + def add_shape(self, shape): """ Adds a shape to the shape storage. @@ -690,6 +709,7 @@ class FlatCAMDraw(QtCore.QObject): self.storage.insert(shape) def deactivate(self): + self.disconnect_canvas_event_handlers() self.clear() self.drawing_toolbar.setDisabled(True) self.snap_toolbar.setDisabled(True) # TODO: Combine and move into tool @@ -740,6 +760,7 @@ class FlatCAMDraw(QtCore.QObject): assert isinstance(fcgeometry, Geometry) self.clear() + self.connect_canvas_event_handlers() self.select_tool("select") # Link shapes into editor. diff --git a/FlatCAMProcess.py b/FlatCAMProcess.py index eb5059ac..a6b2d434 100644 --- a/FlatCAMProcess.py +++ b/FlatCAMProcess.py @@ -10,6 +10,7 @@ class FCProcess(object): "done": [] } self.descr = descr + self.status = "Active" def __del__(self): # print "#######################" @@ -17,6 +18,18 @@ class FCProcess(object): # print "#######################" self.done() + def __enter__(self): + pass + + def __exit__(self, exc_type, exc_val, exc_tb): + if exc_type is not None: + print "Abnormal termination of process!" + print exc_type + print exc_val + print exc_tb + + self.done() + def done(self): # print "FCProcess.done()" for fcn in self.callbacks["done"]: @@ -32,6 +45,9 @@ class FCProcess(object): except ValueError: pass + def set_status(self, status_string): + self.status = status_string + def status_msg(self): return self.descr diff --git a/camlib.py b/camlib.py index 7888ae73..c30d73cb 100644 --- a/camlib.py +++ b/camlib.py @@ -2462,8 +2462,14 @@ class CNCjob(Geometry): "coordinate_format": "X%.4fY%.4f" } - def __init__(self, units="in", kind="generic", z_move=0.1, - feedrate=3.0, z_cut=-0.002, tooldia=0.0, zdownrate=None): + def __init__(self, + units="in", + kind="generic", + z_move=0.1, + feedrate=3.0, + z_cut=-0.002, + tooldia=0.0, + zdownrate=None): Geometry.__init__(self) self.kind = kind @@ -2556,6 +2562,8 @@ class CNCjob(Geometry): gcode += self.pausecode + "\n" for tool in points: + + # Tool change sequence (optional) if toolchange: gcode += "G00 Z%.4f\n" % toolchangez gcode += "T%d\n" % int(tool) # Indicate tool slot (for automatic tool changer) @@ -2564,6 +2572,8 @@ class CNCjob(Geometry): gcode += "(MSG, Change to tool dia=%.4f)\n" % exobj.tools[tool]["C"] gcode += "M0\n" # Temporary machine stop gcode += "M3\n" # Spindle on clockwise + + # Drillling! for point in points[tool]: x, y = point.coords.xy gcode += t % (x[0], y[0]) @@ -3500,6 +3510,12 @@ class FlatCAMRTree(object): self.rti.delete(self.obj2points[objid][i], (pt[0], pt[1], pt[0], pt[1])) def nearest(self, pt): + """ + Will raise StopIteration if no items are found. + + :param pt: + :return: + """ return self.rti.nearest(pt, objects=True).next() diff --git a/tests/destructor_test.py b/tests/destructor_test.py index 83476a4c..c42d8d17 100644 --- a/tests/destructor_test.py +++ b/tests/destructor_test.py @@ -1,6 +1,6 @@ -from time import sleep -from PyQt4 import QtCore -from FlatCAMWorker import Worker +import sys +from PyQt4 import QtCore, QtGui + class MyObj(): @@ -16,19 +16,19 @@ def parse(): raise Exception("Intentional Exception") -if __name__ == "__main__": - qo = QtCore.QObject - worker = Worker(qo) - thr1 = QtCore.QThread() - worker.moveToThread(thr1) - qo.connect(thr1, QtCore.SIGNAL("started()"), worker.run) - thr1.start() +class Example(QtGui.QWidget): - while True: - try: - parse() - print "Parse returned." - except Exception: - pass - sleep(5) - print "Competed successfully." \ No newline at end of file + def __init__(self): + super(Example, self).__init__() + + qbtn = QtGui.QPushButton('Raise', self) + qbtn.clicked.connect(parse) + + self.setWindowTitle('Quit button') + self.show() + + +if __name__ == '__main__': + app = QtGui.QApplication(sys.argv) + ex = Example() + sys.exit(app.exec_()) \ No newline at end of file