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

QQmlPropertyMap 插入;神秘地插入无,或删除其他值

QQmlPropertyMap 插入;神秘地插入无,或删除其他值

www说 2023-02-07 17:15:39
我在 PySide2 和 QML 工作,而 QQmlPropertyList 正在做两件我觉得很奇怪的事情。第一个是如果 QObject 在同一语句中创建,则将其分配为值不起作用:from PySide2.QtCore import QObjectfrom PySide2.QtQml import QQmlPropertyMapqmap = QQmlPropertyMap()qmap.insert('test_key', QObject())print(qmap.value('test_key'))输出:None也许这与 QObject 的初始化时间有关?它可以通过首先将它分配给一个变量来修复:qmap = QQmlPropertyMap()obj = QObject()qmap.insert('test_key', obj)print(qmap.value('test_key'))<PySide2.QtCore.QObject(0x7fe8f26b5eb0) at 0x107075ec0>但它变得陌生。忍受我。分配两个 QObjects 工作:qmap = QQmlPropertyMap()obj = QObject()qmap.insert('test_key', obj)obj2 = QObject()qmap.insert('test_key2', obj2)print(qmap.value('test_key'))print(qmap.value('test_key2'))<PySide2.QtCore.QObject(0x7f85f7f269e0) at 0x10d32b080><PySide2.QtCore.QObject(0x7f85f7f26b70) at 0x10d32b100>我什至可以将同一个对象分配给多个键:qmap = QQmlPropertyMap()obj = QObject()qmap.insert('test_key', obj)qmap.insert('test_key2', obj)print(qmap.value('test_key'))print(qmap.value('test_key2'))<PySide2.QtCore.QObject(0x7fde37d7d9d0) at 0x105cdc140><PySide2.QtCore.QObject(0x7fde37d7d9d0) at 0x105cdc140>但是如果我为两个不同的对象重用相同的变量名,第一个键的值会以某种方式被删除:qmap = QQmlPropertyMap()obj = QObject()qmap.insert('test_key', obj)obj = QObject()qmap.insert('test_key2', obj)print(qmap.value('test_key'))print(qmap.value('test_key2'))None<PySide2.QtCore.QObject(0x7fcecaf072f0) at 0x111ba60c0>怎么会这样?PySide 是否对运行时变量名做了某种隐藏的魔法?在这个例子中它是微不足道的,但它在我的代码中导致了一个很难隔离的错误,我想更好地理解这一点。
查看完整描述

1 回答

?
慕娘9325324

TA贡献1783条经验 获得超4个赞

当您创建一个对象并为其分配相同的变量时,前一个对象被销毁,可以通过以下测试观察到:


class Foo:

    def __del__(self):

        print("destroyed")


print("before creating Foo object: 1")

foo = Foo()

print("after creating Foo object: 1")

print("before creating Foo object: 2")

foo = Foo()

print("after creating Foo object: 2")

输出


before creating Foo object: 1

after creating Foo object: 1

before creating Foo object: 2

destroyed

after creating Foo object: 2

destroyed

正如您所看到的,当第二个对象被分配给同一个变量时,第一个销毁被调用。所以这不是 PySide2 的魔力而是 python 的魔力,同样可以用被破坏的信号来验证。


from PySide2.QtCore import QObject



print("before creating QObject object: 1")

qobject = QObject()

qobject.destroyed.connect(lambda _id=id(qobject): print("destroyed1: ", _id))

print("after creating QObject object: 1")

print("before creating QObject object: 2")

qobject = QObject()

qobject.destroyed.connect(lambda _id=id(qobject): print("destroyed2: ", _id))

print("after creating QObject object: 2")

输出:


before creating QObject object: 1

after creating QObject object: 1

before creating QObject object: 2

destroyed1:  <PySide2.QtCore.QObject(0x562c1b6ee2f0) at 0x7f4a1faece40>

after creating QObject object: 2

如果你不希望这个问题发生,那么使用 Qt 的超能力,你可以将对象作为“qmap”的父对象传递,这样所有权将由 QObject 持有,它将不再由 python 处理:


from PySide2.QtCore import QObject

from PySide2.QtQml import QQmlPropertyMap



qmap = QQmlPropertyMap()


obj = QObject(qmap)

qmap.insert("test_key", obj)


obj = QObject(qmap)

qmap.insert("test_key2", obj)


print(qmap.value("test_key"))

print(qmap.value("test_key2"))

输出:


<PySide2.QtCore.QObject(0x559629d1e230) at 0x7fef951f01c0>

<PySide2.QtCore.QObject(0x559629d1eae0) at 0x7fef951f0240>

更新:


为了更好地理解,我们必须知道PySide2(PyQt5也适用)的QObject是Qt的QObject的包装器,也就是说,它是这样的:


class PyQObject:

    def __init__(self, *args):

        self._qobject_cpp = CPPQObject(*args)

        # ...

    def __del__(self):

        delete self._qobject_cpp


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

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信