3

我在使用 PyQt 创建窗口应用程序时遇到了一些麻烦。例如:我们有以下 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):
        ...

如果我们只想使用它来显示结果和接受用户输入,并且对于所有控制逻辑,我们还有另一个类,它使用实例SampleMainWindow作为字段:

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

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

因此,如果我们创建 的实例Programm,应用程序将运行良好,但在关闭时,我们会收到 python.exe 进程无法正常完成的错误。但是如果实例SampleMainWindow不是类的字段:

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

应用程序关闭良好。什么原因?

下面是完整版的 Gui 类:

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")
4

2 回答 2

4

这与python的垃圾收集有关 - 因为(几乎)很快一个对象不再被引用它会破坏它,所以我猜只要窗口没有被垃圾收集,这个过程就不会终止。

您可以尝试在末尾添加del Programm.window或类似的内容(可能有更好的方法,但我自己从未编写过 QT,所以在这里我无法为您提供帮助)

于 2012-10-10T20:31:53.293 回答
2

看到这个:

from PyQt4.QtCore import * 
from PyQt4.QtGui import * 
import sys 

class MyWindow(QWidget): 
    def __init__(self, parent=None): 
        QWidget.__init__(self, parent) 
        self.label = QLabel("Hi, I'm a window", self) 
        self.button = QPushButton("&Quit", self) 
        self.connect(self.button, SIGNAL("clicked()"), QCoreApplication.instance(), SLOT("quit()")) 

        lay = QVBoxLayout() 
        lay.addWidget(self.label) 
        lay.addWidget(self.button) 
        self.setLayout(lay) 

    def closeEvent(self, event): 
        print "Closing the app" 
        self.deleteLater() 

if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    mw = MyWindow() 
    mw.show() 
    sys.exit(app.exec_())  

解决方案是实现 closeEvent 方法

于 2016-04-24T17:32:44.523 回答