web-dev-qa-db-ja.com

PyQt:XをクリックしてもcloseEventはトリガーされません

私はPyQtの初心者で、簡単なアプリケーションを開発しようとしています。 Qt-designerでシンプルなUIをデザインしました。ユーザーが[X]または[終了]ボタンをクリックするか、メニューから[終了]を選択したときに、本当にアプリケーションを終了するかどうかをさらに確認したい。

コードは次のとおりです。

import sys
from PyQt4 import QtGui, QtCore, uic

class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)

        self.ui = uic.loadUi('main_window.ui')
        self.ui.show()

        self.ui.btnExit.clicked.connect(self.close)
        self.ui.actionExit.triggered.connect(self.close)

    def closeEvent(self, event):
        print("event")
        reply = QtGui.QMessageBox.question(self, 'Message',
            "Are you sure to quit?", QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)

        if reply == QtGui.QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()


def main():
    app = QtGui.QApplication(sys.argv)
    win = MainWindow()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

問題はそれです:

  • メインウィンドウでXをクリックすると、closeEvent関数がトリガーされません
  • [終了]ボタンをクリックするか、メニューから[終了]を選択すると、機能
    が呼び出されますが、[はい]をクリックしてもアプリケーションは閉じません。

SOでいくつかの質問を見つけてチュートリアルを検索しましたが、そのような問題をカバーするものは何もありませんでした。何が間違っているのでしょうか。

11
Wookie88

あなたがしていることに注意してください:

self.ui = uic.loadUi('main_window.ui')
self.ui.show()

actualウィンドウはインスタンス属性(uiinsidewinwin自体ではありません。また、closeEventは実装されていません。

loadUi インスタンス内に.uiファイルをロードできます。

PyQt4.uic.loadUi(uifile[, baseinstance=None[, package='']])

あなたはそれを使うべきです。これで、コードは次のようになります。

import sys
from PyQt4 import QtGui, QtCore, uic

class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)

        uic.loadUi('main_window.ui', self)

        self.btnExit.clicked.connect(self.close)
        self.actionExit.triggered.connect(self.close)

    def closeEvent(self, event):
        print("event")
        reply = QtGui.QMessageBox.question(self, 'Message',
            "Are you sure to quit?", QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)

        if reply == QtGui.QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()


def main():
    app = QtGui.QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

注:私は__init__のウィンドウをshowするのが好きではありません。明示的が優れています。そこで、それをmainに移動しました。自由に変更してください。

16
Avaris

この行を追加するだけで、私にとってはうまくいきます

self.ui.closeEvent = self.closeEvent

したがって、コードは次のようになります。

import sys
from PyQt4 import QtGui, QtCore, uic

class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)

        self.ui = uic.loadUi('main_window.ui')
        self.ui.closeEvent = self.closeEvent
        self.ui.show()

        self.ui.btnExit.clicked.connect(self.close)
        self.ui.actionExit.triggered.connect(self.close)

    def closeEvent(self, event):
        print("event")
        reply = QtGui.QMessageBox.question(self, 'Message',
            "Are you sure to quit?", QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)

        if reply == QtGui.QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()


def main():
    app = QtGui.QApplication(sys.argv)
    win = MainWindow()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()
14
Anggun Pribadi

これに対する別の簡単な解決策は、app.aboutToQuit.connect(self.close_event)を使用して、ユーザーが閉じるボタンをクリックするたびにcloseEvent関数のコードを実行することです。

サンプルコードはこちら

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

#--------------------------------------------------------------------------------

        app.aboutToQuit.connect(self.closeEvent) #this line is what ur looking for !!!!!!

#--------------------------------------------------------------------------------

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle('Demo')

    #{______________________________________

    def closeEvent(self):
        #Your code here
        print('User has pressed the close button')
        import sys
        sys.exit(0)

    #}______________________________________


if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    MainWindow = QtGui.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
1
Natesh bhat

デザイナから、イベントをメインウィンドウに接続し、デザイナで新しいスロットを追加して、python)のメソッドを実装するだけで、イベント->スロット接続が自動的に行われます。

0
LtWorf