12

我是 PyQt 的新手,试图开发简单的应用程序。我用 Qt-designer 设计了简单的 ui。如果用户真的想在单击 X 或 ,,Exit'' 按钮或从菜单中选择 Exit 时退出应用程序,我需要额外的确认。

这是代码:

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 函数不会触发
  • 当我单击退出按钮或从菜单中选择 ,,Exit'' 时,
    会调用该函数,但单击是不会关闭应用程序。

我发现了一些关于 SO 的问题并搜索了教程,但没有任何内容涵盖此类问题。我究竟做错了什么?

4

4 回答 4

18

请注意,您正在执行以下操作:

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

您的实际窗口是内部ui的实例属性 ( ) 。不是自己。而且它还没有实施。 winwincloseEvent

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()

注意:我不喜欢show__init__. 明确的更好。所以,我把它移到main. 随意修改它。

于 2013-02-12T14:41:40.930 回答
14

它对我有用,只需添加这一行

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()
于 2015-12-15T17:59:26.317 回答
1

另一个简单的解决方案是在用户单击关闭按钮时使用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)
于 2017-07-14T18:14:51.953 回答
0

在设计器中,您可以将事件连接到主窗口,并在设计器中添加新插槽,然后只需在 python 中实现方法,事件->插槽连接将自动完成。

于 2013-02-12T14:50:11.177 回答