python - Python PyQt5 将不再显示此消息复选框添加到 QMessageBox
问题描述
我正在努力让这个工作。我试图从一个 c++ 帖子转换成 python 没有快乐: QMessageBox 带有“不再显示这个”复选框
我的粗略代码如下:
from PyQt5 import QtWidgets as qtw
...
mb = qtw.QMessageBox
cb = qtw.QCheckBox
# following 3 lines to get over runtime errors
# trying to pass the types it was asking for
# and surely messing up
mb.setCheckBox(mb(), cb())
cb.setText(cb(), "Don't show this message again")
cb.show(cb())
ret = mb.question(self,
'Close application',
'Do you really want to quit?',
mb.Yes | mb.No )
if ret == mb.No:
return
self.close()
以上执行没有错误,但复选框未显示(消息框显示)。考虑到我在基因上很愚蠢......而且很慢,非常慢。所以请在我的学习曲线上放轻松
解决方案
在尝试“移植”代码时,了解源语言的基础并对目标有更深入的了解非常重要。
例如,获取代码的第一行和引用的问题:
QCheckBox *cb = new QCheckBox("Okay I understand");
上面的 C++ 行表示正在创建一个 QCheckBox 类型的新对象 (cb),并为其分配了 的结果QCheckBox(...)
,它返回该类的一个实例。为了阐明对象是如何声明的,下面是一个简单的整数变量的创建方式:
int mynumber = 10
这是因为 C++ 和许多语言一样,需要对象类型来声明。
在 Python 中,这是一种动态类型语言,这不是必需的(但从Python 3.6 开始可以),但您仍然需要创建实例,这是通过使用类上的括号来实现的(这导致调用它并导致调用和然后)。你的代码的前两行应该是:__new__
__init__
mb = qtw.QMessageBox()
cb = qtw.QCheckBox()
然后,问题是您每次都使用上述类的新实例调用其他方法。
以实例作为第一个参数隐式调用实例方法(例如setCheckBox
),通常称为self
。
checkboxInstance = QCheckBox()
checkboxInstance.setText('My checkbox')
# is actually the result of:
QCheckBox.setText(checkboxInstance, 'My checkbox')
最后一行或多或少意味着:调用setText
类 QCheckBox 的函数,使用实例和文本作为其参数。事实上,如果 QCheckBox 是一个实际的 python 类,setText()
它看起来像这样:
class QCheckBox:
def setText(self, text):
self.text = text
当您这样做时,cb = qtw.QCheckBox
您只创建了对该类的另一个引用,并且每次cb()
您创建一个新实例;也是如此mb
,因为您创建了对消息框类的另一个引用。
以下行:
mb.setCheckBox(mb(), cb())
是相同的:
QMessageBox.setCheckBox(QMessageBox(), QCheckBox())
由于您每次都在创建新实例,因此结果绝对没有:没有对新实例的引用,并且在处理该行后它们将立即被丢弃(“垃圾收集”,也就是删除)。
这就是上述实际应该如何完成的:
mb = qtw.QMessageBox()
cb = qtw.QCheckBox()
mb.setCheckBox(cb)
cb.setText("Don't show this message again")
现在,您的代码中有一个根本缺陷:question()
是一个静态方法(实际上,对于 Python,它更像是一个类方法)。静态方法和类方法是不作用于实例的函数,而只作用于/作用于类。QMessageBox 的静态方法喜欢question
或使用提供的参数warning
创建 QMessageBox 的新实例,因此您之前在创建的实例上所做的一切都将被完全忽略。
这些方法是方便的函数,无需编写太多代码即可简单地创建消息框。由于这些方法只允许基于它们的参数进行定制(不包括添加复选框),因此您显然不能使用它们,并且您必须明确编码它们“在幕后”所做的事情。
以下是最终代码的外观:
# create the dialog with a parent, which will make it *modal*
mb = qtw.QMessageBox(self)
mb.setWindowTitle('Close application')
mb.setText('Do you really want to quit?')
# you can set the text on a checkbox directly from its constructor
cb = qtw.QCheckBox("Don't show this message again")
mb.setCheckBox(cb)
mb.setStandardButtons(mb.Yes | mb.No)
ret = mb.exec_()
# call some function that stores the checkbox state
self.storeCloseWarning(cb.isChecked())
if ret == mb.No:
return
self.close()
推荐阅读
- react-native - React Native,useState 似乎没有设置值
- logstash - 在 Logstash 中将 DateTime 字符串字段转换为 Unix/Epoch 时间
- java - 单声道不延迟
- python - Matplotlib sharex 未按预期工作
- laravel - Laravel Spatie/Media 使用 PHP 即时生成转换
- c# - 为响应进行 XML 序列化时修改默认命名空间前缀
- javascript - 为什么我的合并失败?地图()查找()[javascript]
- json - JsonSerializer 默默地无法反序列化我的对象
- ios - 编辑通过搜索栏选择的记录时应用程序崩溃
- windows-subsystem-for-linux - 这是导入 WSL 导出、覆盖“默认”安装的正确方法吗?