問題描述
我正在努力讓它發揮作用.我試圖從 c++ 帖子轉置為 python,但沒有任何樂趣:QMessageBox 帶有不再顯示此內容"復選框
I am struggling to get this working. I tried to transpose from a c++ post into python with no joy: QMessageBox with a "Do not show this again" checkbox
我的粗略代碼如下:
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()
上面的執行沒有錯誤,但復選框沒有顯示(消息框顯示).考慮到我在基因上很愚蠢......而且很慢,非常慢.所以請在我的學習曲線上放輕松
the above executes with no errors but the checkbox ain't showing (the message box does). consider that I am genetically stupid... and slow, very slow. so please go easy on my learning curve
推薦答案
嘗試移植"時代碼,重要的是要了解源語言的基礎,對目標有更深入的了解.
When trying to "port" code, it's important to know the basis of the source language and have a deeper knowledge of the target.
例如,獲取代碼的第一行和引用的問題:
For instance, taking the first lines of your code and the referenced question:
QCheckBox *cb = new QCheckBox("Okay I understand");
上面的 C++ 行表示正在創建一個 QCheckBox 類型的新對象 (cb),并為其分配了 QCheckBox(...)
的結果,該結果返回該類的實例.為了闡明對象是如何聲明的,下面是一個簡單的整數變量的創建方式:
The line above in C++ means that a new object (cb) of type QCheckBox is being created, and it's assigned the result of QCheckBox(...)
, which returns an instance of that class. To clarify how objects are declared, here's how a simple integer variable is created:
int mynumber = 10
這是因為 C++ 和許多語言一樣,需要對象 type 來聲明.
This is because C++, like many languages, requires the object type for its declaration.
在 Python 中,這是一種動態類型語言,這不是必需的(但自 Python 3.6 起是可能的),但您仍然需要創建實例,這是通過使用類上的括號來實現的(這會導致 調用 它并導致調用 __new__
然后調用 __init__
).那么你的代碼的前兩行應該是:
In Python, which is a dynamic typing language, this is not required (but it is possible since Python 3.6), but you still need to create the instance, and this is achieved by using the parentheses on the class (which results in calling it and causes both calling __new__
and then __init__
). The first two lines of your code then should be:
mb = qtw.QMessageBox()
cb = qtw.QCheckBox()
然后,問題是您每次都使用上述類的新實例調用其他方法.
Then, the problem is that you're calling the other methods with new instances of the above classes everytime.
實例方法(如setCheckBox
)以實例作為第一個參數隱式調用,通常稱為self
.
An instance method (such as setCheckBox
) is implicitly called with the instance as first argument, commonly known as self
.
checkboxInstance = QCheckBox()
checkboxInstance.setText('My checkbox')
# is actually the result of:
QCheckBox.setText(checkboxInstance, 'My checkbox')
最后一行或多或少意味著:調用類 QCheckBox 的 setText
函數,使用實例和文本作為其參數.事實上,如果 QCheckBox 是一個真正的 Python 類,setText()
應該是這樣的:
The last line means, more or less: call the setText
function of the class QCheckBox, using the instance and the text as its arguments.
In fact, if QCheckBox was an actual python class, setText()
would look like this:
class QCheckBox:
def setText(self, text):
self.text = text
當您執行 cb = qtw.QCheckBox
時,您只創建了對類的 another 引用,而每次執行 cb()
時,您都會創建一個新的實例;mb
也是如此,因為您創建了對消息框類的另一個引用.
When you did cb = qtw.QCheckBox
you only created another reference to the class, and everytime you do cb()
you create a new instance; the same happens for mb
, since you created another reference to the message box class.
下面一行:
mb.setCheckBox(mb(), cb())
等同于:
QMessageBox.setCheckBox(QMessageBox(), QCheckBox())
由于您每次都在創建新實例,因此結果絕對沒有:沒有對新實例的引用,并且在處理該行后它們將立即被丟棄(垃圾收集",也就是刪除).
Since you're creating new instances every time, the result is absolutely nothing: there's no reference to the new instances, and they will get immediately discarded ("garbage collected", aka, deleted) after that line is processed.
實際上應該這樣做:
mb = qtw.QMessageBox()
cb = qtw.QCheckBox()
mb.setCheckBox(cb)
cb.setText("Don't show this message again")
現在,您的代碼中有一個根本缺陷:question()
是一個 static 方法(實際上,對于 Python,它更像是一個類方法).靜態方法和類方法是不作用于實例的函數,而只作用于/作用于類.QMessageBox 的靜態方法,如 question
或 warning
使用提供的參數創建 QMessageBox 的 new instance,因此您之前在實例上所做的一切您創建的內容將被完全忽略.
Now, there's a fundamental flaw in your code: question()
is a static method (actually, for Python, it's more of a class method). Static and class methods are functions that don't act on an instance, but only on/for a class. Static methods of QMessageBox like question
or warning
create a new instance of QMessageBox using the provided arguments, so everything you've done before on the instance you created is completely ignored.
這些方法是方便的函數,它們允許簡單地創建消息框而無需編寫太多代碼.由于這些方法只允許基于它們的參數進行定制(不包括添加復選框),因此您顯然不能使用它們,并且您必須對它們在后臺"執行的操作進行編碼.明確的.
These methods are convenience functions that allow simple creation of message boxes without the need to write too much code. Since those methods only allow customization based on their arguments (which don't include adding a check box), you obviously cannot use them, and you must code what they do "under the hood" explicitly.
這是最終代碼的外觀:
# 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()
這篇關于Python PyQt5 將不再顯示此消息復選框添加到 QMessageBox的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!