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 に答える