mixeus mixeus - 7 months ago 30
Python Question

PyQt application close with error

I have some trouble with creating window application using PyQt. For example: we have the following class for GUI:

class SampleMainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
...

def hideEvent(self, event):
...

def showEvent(self, event):
...

def activate(self):
...

def closeEvent(self, event):
...


What if we want to use it just for showing results and acept user inputs, and for all control logic we have another class, which use the instance of
SampleMainWindow
as a field:

class Programm:
def __init__(self):
self.window = SampleMainWindow()
....

app = QtGui.QApplication(sys.argv)
prog = Programm()
prog.window.show()
app.exec_()


So, if we create the instance of
Programm
, the application will run well, but on close we'll get an error that python.exe process could not be completed normally. But if the instance of
SampleMainWindow
is not a field of class:

class Programm:
def __init__(self):
win = SampleMainWindow()
....


application close well. What's the reason?

Here are the full version of Gui class:

class SampleMainWindow(QtGui.QMainWindow):

def initTray(self):
self.icon = QtGui.QSystemTrayIcon()
self.icon.setIcon(QtGui.QIcon('Tray.png'))
self.icon.show()
self.icon.activated.connect(self.activate)

def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self)
moduleglobalconstants.APP_RUNNING = True
self.initTray()
self.newSession = True

self.setGeometry(300, 300, 600, 400)
self.setWindowTitle('Eye: Recently Added Lines')
self.statusBar().showMessage('Ready')
exitAction = QtGui.QAction(QtGui.QIcon('Exit.png')
,'Exit'
,self)

exitAction.setShortcut('Ctrl+Q')
exitAction.setStatusTip('Exit application')
self.connect(exitAction
,QtCore.SIGNAL('triggered()')
,QtCore.SLOT('close()'))

menubar = self.menuBar()
fileMenu = menubar.addMenu('&File')
fileMenu.addAction(exitAction)

self.toolbar = self.addToolBar('Exit')
self.toolbar.addAction(exitAction)

self.textEdit = QtGui.QTextEdit()
self.scrollPosition = self.textEdit.textCursor()
self.textEdit.setReadOnly(True)
self.setCentralWidget(self.textEdit)

def hideEvent(self, event):
self.hidden = True
self.setWindowFlags(QtCore.Qt.ToolTip)
self.setVisible(False)

def showEvent(self, event):
self.hidden = False
self.setVisible(True)

def activate(self):

self.setWindowFlags(QtCore.Qt.Window)
self.show()
self.setWindowState(self.windowState() & ~QtCore.Qt.WindowMinimized | QtCore.Qt.WindowActive)
self.activateWindow()

def questionDialog(self, caption = 'Message',text = "Are you sure?"):
self.activate()
msgBox = QtGui.QMessageBox(self)
msgBox.setWindowTitle("Eye")
msgBox.setText(caption);
msgBox.setInformativeText(text);
msgBox.setStandardButtons(QtGui.QMessageBox.Yes| QtGui.QMessageBox.No);
msgBox.setDefaultButton(QtGui.QMessageBox.Yes);
return msgBox.exec_()

def criticalDialog(self,app, caption = 'Eye: Critical Error',text = "Impossible to continue working!"):
self.activate()
msgBox = QtGui.QMessageBox.critical(self,caption,text)
moduleglobalconstants.APP_RUNNING = False

def closeEvent(self, event):
reply = self.questionDialog()
if reply == QtGui.QMessageBox.Yes:
moduleglobalconstants.APP_RUNNING = False
event.accept()
else:
event.ignore()

def showNewLines(self, singleLine = None, lines = None, mode='insert'):
if (mode == 'rewrite'):
self.textEdit.clear()
if lines:
for line in lines:
self.textEdit.insertPlainText(line.strip() + "\n")
elif singleLine:
self.textEdit.insertPlainText(singleLine.strip()+"\n")

Answer

This has to do with python's garbage collecting - as (almost) soon an object isn't referenced anymore it destroys it, so I guess the process doesn't terminate as long as the window wasn't garbage-collected.

You can try to add at the end del Programm.window or something like that (there's probably a better way of doing this, but I never programmed QT myself so I can't help you here)

Comments