2012-10-10 44 views
3

我在使用PyQt創建窗口應用程序時遇到了一些麻煩。例如:我們有一個GUI下面的類:PyQt應用程序關閉,出現錯誤

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

    def hideEvent(self, event): 
     ... 

    def showEvent(self, event): 
     ... 

    def activate(self): 
     ... 

    def closeEvent(self, event): 
     ... 

如果我們想用它只是爲了顯示結果和acept用戶輸入,並且我們有另一個類,它使用的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() 
     .... 

應用程序關閉好。什麼原因?

這裏是桂類的完整版本:

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") 
+0

我想你的代碼有一些膽量添加到主窗口,但一切似乎都運行良好與退出沒有錯誤。如果我將'self.win = SampleMainWindow()'改爲'win = SampleMainWindow()',會產生錯誤,因爲__init__正在結束,並且不再引用局部變量'win'。你能提供更多關於你所看到的錯誤的細節嗎? – Jonathan

+0

在linux上我也有這個「問題」。它_sometimes_「關閉」與段錯誤。但自從程序運行良好以來,我並不在乎,而且在關閉時必須完成的任何事情都已完成完成......只是在正確關閉之前解釋器纔會暫停。 – Bakuriu

+0

問題在於操作系統可能會捕獲退出狀態並顯示惱人的對話框;當我做出一些拼寫錯誤時,發生在我的很多Ubuntu中。 – lolopop

回答

3

這有做Python的垃圾收集 - 爲(幾乎)不久的對象不再被引用它會破壞它,所以我猜的過程只要窗口沒有被垃圾收集,它就不會終止。

您可以嘗試在年底del Programm.window或類似的東西增加(可能有這樣做的更好的辦法,但我從來沒有編程QT自己,所以我不能幫你在這裏)

+1

看來,你是對的......我已經簡單地在退出之前添加了'del Programm.window',並且錯誤消失了,非常感謝! – mixeus

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

+0

對不起,我需要添加並調用self.deleteLater() – samy

相關問題