如果拒绝对话框,PyQt应用程序会冻结
我有一个小应用程序,在启动之前需要用户登录。可是如果用户拒绝登录(按下取消按钮),应用程序不会关闭,而是会卡住。
下面是简化后的代码:
import sys
from PyQt5 import QtWidgets, QtCore
class LoginWindow(QtWidgets.QDialog):
def __init__(self, parent=None):
super(LoginWindow, self).__init__(parent)
self.resize(250, 150)
self.move(500, 500)
self.setWindowTitle('Login')
self.login_input = QtWidgets.QLineEdit(self)
self.login_input.move(10, 10)
self.password_input = QtWidgets.QLineEdit(self)
self.password_input.move(10, 50)
self.password_input.setEchoMode(QtWidgets.QLineEdit.Password)
self.button_box = QtWidgets.QDialogButtonBox(self)
self.button_box.move(10, 80)
self.button_box.setOrientation(QtCore.Qt.Horizontal)
self.button_box.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel |
QtWidgets.QDialogButtonBox.Ok)
self.button_box.accepted.connect(self.login)
self.button_box.rejected.connect(self.reject)
def login(self):
self.accept()
def cancel(self):
self.reject()
class MainWindow(QtWidgets.QDialog):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.resize(250, 150)
self.move(500, 500)
self.setWindowTitle('Main')
self.input = QtWidgets.QLineEdit(self)
self.input.move(10, 10)
self.show()
def main():
app = QtWidgets.QApplication([])
l = LoginWindow()
l.show()
login_result = l.exec_()
print(login_result)
if login_result == QtWidgets.QDialog.Accepted:
m = MainWindow()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
我哪里做错了?我使用的是Python 3和PyQt5。
2 个回答
1
我找到了一种方法来避免这个错误:
我修改了主函数:
def main():
app = QtWidgets.QApplication([])
if LoginWindow().exec_() == QtWidgets.QDialog.Accepted:
m = MainWindow()
sys.exit(app.exec_())
现在它正常工作了,但我还是不明白,问题的根本原因是什么。
2
这个问题发生是因为PySide还没有处理任何事件。
app.exec_()
这段代码启动了一个主事件循环,它会不断处理每一次图形界面的互动。在你执行任何图形界面代码之前,应该先调用这个循环,这样事件才能正确地从事件队列中处理。
QDialog.exec_()是一个阻塞操作,这意味着在得到响应之前,代码不会继续执行。
如果你想看到对话框里的内容,可能有办法绕过这个问题。
QtGui.QApplication.processEvents()
这段代码会处理事件队列中的所有事件,所以你可能需要不断调用这个方法。
另外,在你初始化主窗口之后,还需要把主窗口显示出来。