Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么PyQt5小部件有时具有相同的id?_Python_Qt_Pyqt5_Weak References_Qformlayout - Fatal编程技术网

Python 为什么PyQt5小部件有时具有相同的id?

Python 为什么PyQt5小部件有时具有相同的id?,python,qt,pyqt5,weak-references,qformlayout,Python,Qt,Pyqt5,Weak References,Qformlayout,(示例问题代码及其在底部的输出) 使用PyQt5,我正在编写一个QDialog,其中包含QTabWidget。 此选项卡小部件具有QFormLayout布局。 我想迭代表单并将其右侧小部件(“字段”)作为键存储在weakref.WeakKeyDictionary中,以备以后使用(直到对话框关闭且相应的键有望自动消失) 我发现我的弱键dict并没有像预期的那样工作:一些小部件被正确地存储了,一些没有。 特别是,后来添加的小部件似乎存储得更频繁(当我多次退出并重新打开应用程序时) 我为表单中的每个标

(示例问题代码及其在底部的输出)

使用PyQt5,我正在编写一个
QDialog
,其中包含
QTabWidget
。 此选项卡小部件具有
QFormLayout
布局。 我想迭代表单并将其右侧小部件(“字段”)作为键存储在
weakref.WeakKeyDictionary
中,以备以后使用(直到对话框关闭且相应的键有望自动消失)

我发现我的弱键dict并没有像预期的那样工作:一些小部件被正确地存储了,一些没有。 特别是,后来添加的小部件似乎存储得更频繁(当我多次退出并重新打开应用程序时)

我为表单中的每个标签小部件
label
调用了
print(hex(id(label))
。 这表明一些标签具有相同的Python
id
,我相信只有最后一个迭代过的具有特定id的小部件被存储

这种“id共享”真的是我的弱键dict不能存储所有小部件的原因吗? 为什么每个小部件没有自己的id? 我是否可以更改代码,使每个小部件都有一个唯一的id? 我是否可以更改代码,使每个小部件在我的弱键dict中只存储一次

示例代码:

!/usr/bin/env python3
从weakref导入WeakKeyDictionary
从PyQt5.QtCore导入pyqtlot
从PyQt5.QtWidgets导入*
类主窗口(QMainWindow):
定义初始化(自):
super()。\uuuu init\uuuuu()
self.weak=WeakKeyDictionary()
self.clickme=QPushButton(“单击我”,self)
self.clickme.clicked.connect(self.open\u设置)
@pyqtSlot()
def open_设置(自身)->无:
dialog=QDialog(self)
self.weak[对话框]=“设置”
grid=QGridLayout()
tabs=QTabWidget(对话框)
tab0=QWidget(选项卡)
tabs.addTab(tab0,“样本”)
form0=QFormLayout()
对于“示例”中的字符:
form0.addRow(char,QLineEdit(tab0))
表0.setLayout(表格0)
#打印信息
对于范围内的行(form0.rowCount()):
label=form0.itemAt(行,form0.LabelRole).widget()
打印(十六进制(id(标签)),类型(标签)。\uuuuuu名称\uuuuuuuuuu)
self.weak[label]=“foobar”
打印(刷新=真)
对于self.weak.items()中的k,v:
打印(f“{k!r}:{v!r}”)
打印(刷新=真)
addWidget(选项卡,0,0,1,3)
dialog.show()
dialog.exec()
如果名称=“\uuuuu main\uuuuuuuu”:
app=QApplication([])
窗口=主窗口()
window.show()
app.exec()
整个应用程序运行时此示例代码的输出:

0x7f5956285670 QLabel#这没问题
0x7f5956285700 QLabel#这没问题
0x7f59562855e0 QLabel#这没问题
0x7f5956285670 QLabel#为什么重复id?!
0x7f5956285700 QLabel#为什么重复id?!
0x7f59562855e0 QLabel#为什么重复id?!
#由此产生的弱键命令:
:“设置”
:“foobar”

<代码> > p>它似乎是一个bug,它似乎发生在C++中创建对象时(像qFraseDebug的QWIDGeTEM),然后当它从Python访问时,似乎PyQT5重用对象(在PySID2中它不会发生)。 一个可能的解决方案是在python中创建QLabel,这样就不会重用对象

form0.addRow(QLabel(char), QLineEdit())
form0.addRow(QLabel(char),QLineEdit())
此外,您必须访问QLabel而不是QWidgetItem:

# print information
for row in range(form0.rowCount()):
    label = form0.itemAt(row, form0.LabelRole).widget()
    print(hex(id(label)), type(label).__name__)
    self.weak[label] = "foobar"
print(flush=True)
#打印信息
对于范围内的行(form0.rowCount()):
label=form0.itemAt(行,form0.LabelRole).widget()
打印(十六进制(id(标签)),类型(标签)。\uuuuuu名称\uuuuuuuuuu)
self.weak[label]=“foobar”
打印(刷新=真)
输出:

0x7f756703c0d0 QLabel
0x7f756703c1f0 QLabel
0x7f756703c310 QLabel
0x7f756703c430 QLabel
0x7f756703c550 QLabel
0x7f756703c670 QLabel

<PyQt5.QtWidgets.QDialog object at 0x7f756ef61dc0>: 'Settings'
<PyQt5.QtWidgets.QLabel object at 0x7f756703c0d0>: 'foobar'
<PyQt5.QtWidgets.QLabel object at 0x7f756703c1f0>: 'foobar'
<PyQt5.QtWidgets.QLabel object at 0x7f756703c310>: 'foobar'
<PyQt5.QtWidgets.QLabel object at 0x7f756703c430>: 'foobar'
<PyQt5.QtWidgets.QLabel object at 0x7f756703c550>: 'foobar'
<PyQt5.QtWidgets.QLabel object at 0x7f756703c670>: 'foobar'
0x7f756703c0d0 QLabel
0x7f756703c1f0 QLabel
0x7f756703c310 QLabel
0x7f756703c430 QLabel
0x7f756703c550 QLabel
0x7f756703c670 QLabel
:“设置”
:“foobar”
:“foobar”
:“foobar”
:“foobar”
:“foobar”
:“foobar”

我不完全确定它实际上是一个bug,考虑到pyQt对象只是对C++绑定的引用:只要Python引用存在于同一个范围内,IDS就可以匹配。在处理QMeta对象时,我注意到了类似的行为:而小部件。
是真的,如果你做
x=id(widget.metaObject())
然后做
y=id(widget.metaObject())
它们是不同的。我忘了添加
.widget()
当我将实际代码转换为一个最小的示例时。我编辑了问题以添加它,因为我真正的问题不是检索QLabel。但是请告诉我是否应该保持问题的原始状态。@musicamante我说这是一个bug,并不是因为此实现不正确,而是因为它没有文档记录。