英文:
PySide6 QCheckBox stateChanged() generates state event int instead of Qt.CheckState
问题
以下是翻译好的部分:
"PySide6 6.4.1 PIP on Ubuntu and Windows contains a QCheckBox
with stateChanged()
API call to generate an event when the checkbox state changes."
"QCheckBox的生成的事件参数
state的类型是
int而不是枚举
CheckState`:"
"下面的测试用例演示了不起作用的复选框事件状态:"
"我不知道如何将Qt.Checked
,Qt.PartiallyChecked
或Qt.Unchecked
转换为int
。"
"使用if state == int(Qt.Checked)
进行强制转换会生成以下错误:"
"TypeError: int() argument must be a string, a bytes-like object or a real number, not 'CheckState'"
"这是否是预期行为?"
英文:
PySide6 6.4.1 PIP on Ubuntu and Windows contains a QCheckBox
with stateChanged()
API call to generate an event when the checkbox state changes.
- QCheckBox documentation:
state contains the checkbox’s new CheckState
.
- PySide6.QtCore.Qt.CheckState documentation:
This enum describes the state...
Qt.Checked: The item is checked.
.
The QCheckBox
generated event argument state
is type int
instead of enum CheckState
:
Testcase below demonstrates not working checkbox event state:
from PySide6.QtWidgets import QApplication, QWidget, QCheckBox
from PySide6.QtCore import Qt
import sys
class Window(QWidget):
def __init__(self):
super().__init__()
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle('QCheckBox')
checkbox = QCheckBox('Show title', self)
checkbox.move(20, 20)
checkbox.toggle()
checkbox.setTristate(True)
checkbox.stateChanged.connect(self.onCheckboxChange)
def onCheckboxChange(self, state):
# state = int and not Qt.Checked or Qt.Unchecked
# This is not matching with the documentation
print('Qt.Checked type: {}'.format(type(Qt.Checked)))
print('Event: {}, type: {}'.format(state, type(state)))
# Always setting title to UNKNOWN as this is an incorrect type comparison
if state == Qt.Unchecked:
self.setWindowTitle('Unchecked')
elif state == Qt.PartiallyChecked:
self.setWindowTitle('PartiallyChecked')
elif state == Qt.Checked:
self.setWindowTitle('Checked')
else:
self.setWindowTitle('UNKNOWN')
def main():
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec())
if __name__ == '__main__':
main()
Output:
# When unchecking checkbox:
Qt.Checked type: <enum 'CheckState'>
Event: 0, type: <class 'int'> <= Expected Qt.Unchecked:
# When partially checking checkbox:
Qt.Checked type: <enum 'CheckState'>
Event: 1, type: <class 'int'> <= Expected Qt.PartiallyChecked:
# When checking checkbox:
Qt.Checked type: <enum 'CheckState'>
Event: 2, type: <class 'int'> <= Expected Qt.Checked:
I don't know how to convert the Qt.Checked
, Qt.PartiallyChecked
or Qt.Unchecked
to an int
.
Casting with if state == int(Qt.Checked)
generates:
TypeError: int() argument must be a string, a bytes-like object or a real number, not 'CheckState'
Is this expected behavior?
答案1
得分: 0
这是正确的,也是预期的行为。
如果您仔细阅读文档,您会发现 stateChanged
参数的类型确实是int
:
PySide6.QtWidgets.QCheckBox.stateChanged(arg__1)
参数
arg__1
- int
尽管这可能看起来令人意外和不一致,但这就是我们现在的情况。我不知道为什么,但我怀疑这是由于历史原因。
从Qt6开始,Python绑定(PySide和PyQt)都已经切换到了实际的Python枚举,这可能会引发一些混淆。
现在,只有继承自enum.IntEnum
的枚举才能进行int()
转换,而这对于 Qt.CheckState
并不成立,但对于其他一些枚举(例如,Qt.ItemDataRole
)是成立的。
如果您想要比较stateChanged
的结果,那么可以将值转换为枚举:
if Qt.CheckState(state) == Qt.Checked:
或者获取枚举的 value
:
if state == Qt.Checked.value:
关于术语的一些重要说明:1. stateChanged
是一个 信号,而不是一个 "API 调用"(事实上,信号甚至不可调用);2. 信号不是事件,至少在Qt术语中是这样:事件是由系统(或合成)生成的事件,通常是由系统生成,要么是由用户交互引发的,要么是由系统本身引发的。
英文:
It is not wrong, and it is the expected behavior.
If you read the documentation more carefully, the type of the argument is int
for stateChanged
:
> PySide6.QtWidgets.QCheckBox.stateChanged(arg__1)
> PARAMETERS
> arg__1
- int
While it might seem unexpected and inconsistent, that's what we have. I don't know why, but my suspect is that it's for historical reasons.
Starting with Qt6, both python bindings (PySide and PyQt) have switched to actual python enums, and this can create some level of confusion.
int()
conversion is now only possible for enums that actually inherit from enum.IntEnum
, which is not the case for Qt.CheckState
, but it is for some others (for example, Qt.ItemDataRole
).
If you want to compare the result of stateChanged
, then either convert the value to the enum:
if Qt.CheckState(state) == `Qt.Checked`:
Otherwise get the value
:
if state == Qt.Checked.value:
<sup>Some important notes about terminology: 1. stateChanged
is a signal, not an "API call" (in fact, signals are not even callable); 2. signals are not events, at least in Qt terms: events are system (or synthesized) events that are normally generated by the system, either by user interaction or caused by the system itself;</sup>
答案2
得分: 0
stateChanged signal发送一个整数,如文档所示,因此行为符合预期。解决方法是转换为Qt.CheckState:
def onCheckboxChange(self, state_int):
state = Qt.CheckState(state_int)
英文:
The stateChanged signal sends an int as indicated in the docs, so the behavior is as expected. The solution is to convert to Qt.CheckState:
def onCheckboxChange(self, state_int):
state = Qt.CheckState(state_int)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论