Ok. So, I've been trying to figure this out for a while and I'm just stuck. Everytime I try to run this, the window just opens and closes immediately. I just can't seem to figure it out. Please help.
FYI. This is a macro for FreeCAD that creates cylinders. I've made other macros before and they work just fine. I didn't start having trouble until I introduced the PyQt GUI.
import FreeCAD, math
from FreeCAD import Base, Draft, Part
from PyQt4 import QtGui, QtCore
class Muffler(QtGui.QWidget):
def __init__(self):
super(Muffler, self).__init__()
self.initUI()
def initUI(self):
#Introduce Labels and inputs
self.t0 = QtGui.QLabel("Cylinder",self)
self.t01 = QtGui.QLabel(" ",self)
self.t1 = QtGui.QLabel("Radius of Cylinder (mm)",self)
self.l1 = QtGui.QLineEdit(self)
self.l1.setText("31.75")
self.t2 = QtGui.QLabel("Length of Cylinder (mm)",self)
self.l2 = QtGui.QLineEdit(self)
self.l2.setText("50")
#Create buttons
self.createButton = QtGui.QPushButton("Create",self)
self.cancelButton = QtGui.QPushButton("Cancel",self)
#Create window and size it
layout = QtGui.QGridLayout()
self.resize(240,180)
self.setWindowTitle("Cylinder")
#Design Layout of window
layout.addWidget(self.t0, 0, 0)
layout.addWidget(self.t01, 0, 1)
layout.addWidget(self.t1, 1, 0)
layout.addWidget(self.l1, 1, 1)
layout.addWidget(self.t2, 2, 0)
layout.addWidget(self.l2, 2, 1)
layout.addWidget(self.createButton, 3, 0)
layout.addWidget(self.cancelButton, 3, 1)
#Set Layout and show it
self.setLayout(layout)
self.show()
#Give functionality to the buttons
QtCore.QObject.connect(self.createButton, QtCore.SIGNAL('clicked()'),self.build)
QtCore.QObject.connect(self.cancelButton, QtCore.SIGNAL('clicked()'),self.close)
def build(self):
#some code
def close(self):
self.hide()
Muffler()
FreeCAD is a Qt Application, that means if will already have instantiated a QApplication
and called it's exec_()
method. Therfore you don't need to do that in your script, as that can - as you found out - freeze or crash the whole application.
As it seems, macros in FreeCAD are compiled and executed using exec()
, and therefore their state (global variables) are not preserved once the execution has finished. That means that any QObjects which are owned by PyQt and not by Qt (which basically are all QObjects that have no parent) will be destroyed when they're garbaged collected.
A simple solution to this would be to create a reference outside the macro that will keep the object from being collected. Candidates where to put such a reference could be the __main__
or any other python module:
...
import __main__
__main__.muffler = Muffler()
...