在Qt Designer中创建一个简单的Widget窗体,只包含一个pushButton按钮,想要单击该按钮后弹出一个子窗口。
但是实际运行时发现子窗口闪退。
创建Widget窗体后,先转为py文件,然后新建一个CallMainUI.py文件用来对基本UI界面做修改及添加信号与槽的响应。
在CallMainUI.py文件中设置单击pushButton弹出一个列表对话框:
class MainWin(QMainWindow, Ui_Form):
def __init__(self):
super().__init__()
self.setupUi(self)
self.pushButton.clicked.connect(self.pop_win)
def pop_win(self):
lst_widget = QListWidget()
lst_widget.addItems(['item1', 'item2', 'item3'])
lst_widget.show()
运行后,点击按钮,子窗口闪退了。为什么呢?
对话框分为两种:模态对话框与非模态对话框
模态对话框:在弹出模态窗口时会锁定整个程序,使之处于等待状态,直到用户关闭该对话框。这时往往需要对话框的返回值进行接下来的操作。如确认对话框,需要点击是或否关闭它。
非模态对话框,当非模态对话框被打开时,用户可以和该对话框进行交互,也可以选择同应用程序的其他窗口交互。如查找框。
显示窗口的2个函数:
show() 显示一个非模态对话框,在调用弹出窗口之后,调用即刻返回给调用函数,继续下面的操作。函数执行完后,弹出窗口就被释放了。
exec() 显示一个模态对话框,调用exec()后,调用线程将会被阻塞,锁住程序直到用户关闭该对话框。
所以子窗口闪退的原因是,QListWidget子窗体通过show()显示出来,执行完pop_win方法后,该子窗体即刻被销毁了,所以现象是该子窗口闪退。
可以改为lst_widget.exec(),显示一个模态对话框吗?——不可以,Widget没有exec()方法,exec()方法是QDialog类的一个方法。
①使子窗体lst_widget变为主窗口类的属性,这样子窗体实例在出了函数作用域也不会被销毁。
此时show方法显示一个非模态对话框,用户可以再返回主界面点击pushButton按钮。
def pop_win(self):
self.lst_widget = QListWidget()
self.lst_widget.addItems(['item1', 'item2', 'item3'])
self.lst_widget.show()
# lst_widget.exec()
此时如果想设置为模态对话框,可设置窗口模态属性 为 模态:
def pop_win(self):
self.lst_widget = QListWidget()
self.lst_widget.setWindowModality(Qt.ApplicationModal) # 设置模态属性
self.lst_widget.addItems(['item1', 'item2', 'item3'])
self.lst_widget.show()
如果是在Qt设计器中绘制窗口,也可以在Qt设计器的属性编辑器中设置窗口模态值:
②使lst_widget在一个可执行exec()的Dialog对话框中。
此时exec方法显示的子窗口是一个模态对话框,不关闭该子窗口直接返回主界面操作会报错。
def pop_win1(self):
dialog_win = QDialog()
dialog_win.setWindowTitle('item list')
v_layout = QVBoxLayout(dialog_win)
lst_widget = QListWidget()
lst_widget.addItems(['item1', 'item2', 'item3'])
v_layout.addWidget(lst_widget)
dialog_win.exec()