PyQt5 弹出子对话框时闪退的原因分析和解决方法

在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设计器的属性编辑器中设置窗口模态值:

 PyQt5 弹出子对话框时闪退的原因分析和解决方法_第1张图片

 

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

PyQt5 弹出子对话框时闪退的原因分析和解决方法_第2张图片

你可能感兴趣的:(PyQt5)