为了账号安全,请及时绑定邮箱和手机立即绑定

PyQt5 应用程序中的故障排除(QDialog -> QMainWindow)

PyQt5 应用程序中的故障排除(QDialog -> QMainWindow)

青春有我 2023-02-22 13:52:42
我目前正在尝试解决我在使用 Python 开发的 Qt 应用程序时遇到的问题。我只有一个简单的主窗口和一个模态 QDialog 设置,用于在主窗口上触发菜单操作后收集用户输入。QDialog 的行为符合预期,因为我已经能够确认测试打印是在 QDialog 返回 Accepted 时执行的,但是应用程序将在 print 语句之后完全崩溃,没有错误消息。当 QDialog 返回 Rejected 时会发生相同的行为。澄清一下,主窗口显示了几秒钟,应用程序崩溃了,没有错误消息。我希望该函数在收到来自下面的 Process 函数的任一结果后,将焦点返回到主窗口(它仍然打开以进行操作)。我还尝试使 QDialog 成为无模式的(使用 show),并且 QDialog 的接受/拒绝函数似乎按预期返回到主窗口,但是再次调用调出 QDialog 的函数会使应用程序崩溃。我在这个项目中使用 pyqt 5.9,但我在 pyqt 5.6 的许多其他项目中使用了与下面代码基本相同的设置,但没有发生这种情况。我试图弄清楚 pyqt 5.9 是否存在任何可能导致此问题的已知问题,或者我的代码中是否存在导致此崩溃发生的错误。我正在考虑回滚到 5.6 看看是否可以解决这个问题,但我觉得可能是我误解了导致这种情况发生的原因。我在 Windows 10 上通过 Anaconda 提示符(Anaconda 4.8.3、Python 3.7)运行代码,因为 Qt 应用程序在 Spyder 中重复运行时仍然存在问题。我正在使用 Anaconda 附带的 pyqt,并且没有对 pyqt 进行任何额外的 pip 安装。主窗口代码import sysfrom PyQt5.QtCore import Qtfrom PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QGridLayout, QHBoxLayout, QVBoxLayout, QAction, QLabelfrom PyQt5.QtWidgets import QDialog, QListWidget, QListWidgetItem, QAbstractItemView, QPushButton, QLineEdit, QSpacerItem, QSizePolicyclass FirstWindow(QMainWindow):    def __init__(self):        QMainWindow.__init__(self)                self.title = 'Window 1'        self.left = 350        self.top = 150        self.width = 800        self.height = 500                self.setWindowTitle(self.title)        self.setGeometry(self.left,self.top,self.width,self.height)                widget = QWidget()        self.setCentralWidget(widget)        grid = QGridLayout()        widget.setLayout(grid)                mainMenu = self.menuBar()        mainMenu.setNativeMenuBar(False)        subMenu = mainMenu.addMenu('File')                modifyDB = QAction('Test',self)        subMenu.addAction(modifyDB)        modifyDB.triggered.connect(self.Process)                self.statusBar().showMessage('Ready')    def Process(self):        dialog = DialogWin()        if dialog.exec_() == QDialog.Accepted:            print('test passed')
查看完整描述

1 回答

?
慕沐林林

TA贡献2016条经验 获得超9个赞

解释:

问题是您使用了同一个 QSpacerItem 2 次,当 QDialog 关闭时,因为它是一个局部变量,它将被删除,Qt 也会消除内部对象,在这种情况下,QSpacerItem 将被双重消除导致“分段错误”。


解决方案:

您必须创建 2 个 QSpacerItem:


# ...

hbox = QHBoxLayout()

hbox.addItem(spacer)

self.option_exp = QLabel('OR')

hbox.addWidget(self.option_exp)

hbox.addItem(QSpacerItem(10,10,QSizePolicy.Expanding,QSizePolicy.Expanding))

vbox.addLayout(hbox)

# ...

另一种选择是不使用 QSpacerItem 而是设置一个拉伸因子:


# ...

hbox = QHBoxLayout()

hbox.addStretch()

self.option_exp = QLabel('OR')

hbox.addWidget(self.option_exp)

hbox.addStretch()

vbox.addLayout(hbox)

# ...

或者不使用 QHBoxLayout 并通过设置对齐方式将 QLabel 直接设置为 QVBoxLayout:


# ...

self.table_list = QListWidget()

self.table_list.setSelectionMode(QAbstractItemView.SingleSelection)

vbox.addWidget(self.table_list)


self.option_exp = QLabel('OR')

vbox.addWidget(self.option_exp, alignment=Qt.AlignHCenter)

   

self.new_name = QLineEdit(placeholderText='Enter New Source Name')       

vbox.addWidget(self.new_name)

# ...


查看完整回答
反对 回复 2023-02-22
  • 1 回答
  • 0 关注
  • 312 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号