PyQt5问题:用QtDesigner创建的QMainWindow为何无法正常显示?
问题
我尝试用QtDesigner制作一个简单的Hello World界面,通过pyuic5导出为qthelloworld.py,代码如下:
# Form implementation generated from reading ui file '.\qtdesigner_test.ui' # # Created by: PyQt5 UI code generator 5.15.9 # # WARNING: Any manual changes made to this file will be lost when pyuic5 is # run again. Do not edit this file unless you know what you are doing. from PyQt5 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(800, 600) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.horizontalLayoutWidget = QtWidgets.QWidget(self.centralwidget) self.horizontalLayoutWidget.setGeometry(QtCore.QRect(9, 9, 771, 551)) self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget") self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget) self.horizontalLayout.setContentsMargins(0, 0, 0, 0) self.horizontalLayout.setObjectName("horizontalLayout") self.pushButton = QtWidgets.QPushButton(self.horizontalLayoutWidget) self.pushButton.setObjectName("pushButton") self.horizontalLayout.addWidget(self.pushButton) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21)) self.menubar.setObjectName("menubar") self.menuI_have_typed_here = QtWidgets.QMenu(self.menubar) self.menuI_have_typed_here.setObjectName("menuI_have_typed_here") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.menubar.addAction(self.menuI_have_typed_here.menuAction()) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.pushButton.setText(_translate("MainWindow", "Hello World!")) self.menuI_have_typed_here.setTitle(_translate("MainWindow", "I have typed here"))
随后编写了运行脚本:
from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtWidgets import QApplication import sys from qthelloworld import Ui_MainWindow class Window(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self, parent=None): super().__init__(parent) self.setupUi(self) def main(): app = QApplication(sys.argv) win = Window() win.show() app.exec() if __name__ == '__main__': main()
此前手动创建过相同结构的PyQt5程序,运行正常,但此次用QtDesigner生成的窗口仅短暂闪烁后就关闭了。请问哪里操作出错了?
解决方案
问题出在运行脚本的事件循环调用上。在PyQt5中,exec是Python的关键字,因此PyQt5将事件循环方法命名为exec_()(带下划线),而非exec()。
你当前调用的app.exec()并没有正确启动Qt的事件循环,程序执行到此处后直接退出,导致窗口一闪而过。
修改运行脚本中的main函数,将app.exec()替换为app.exec_()即可:
def main(): app = QApplication(sys.argv) win = Window() win.show() app.exec_() # 替换为exec_()
此外,也可以使用sys.exit(app.exec_())确保程序退出时正确清理资源,写法如下:
def main(): app = QApplication(sys.argv) win = Window() win.show() sys.exit(app.exec_())
修改完成后,窗口就能正常显示并保持打开状态。
内容的提问来源于stack exchange,提问作者Joonas Joensuu
相关产品推荐
相关产品推荐

