将 QObject 指针从 QML 对象传递给 C++

Posted

技术标签:

【中文标题】将 QObject 指针从 QML 对象传递给 C++【英文标题】:Passing QObject pointer from a QML object to C++ 【发布时间】:2018-02-09 10:50:12 【问题描述】:

我在 Qt/C++ 中有一个发布者/订阅者键值数据库类。订阅者可以通过传递键(字符串)、他们的 QObject 指针和属性来连接。 每当订阅键的值改变时,订阅的 QObject 的属性就会改变为新值。在 Qt/C++ 中运行良好。

现在我想在 QML 中创建一个视图。是否可以从 QML 向 C++ 传递具有 3 个参数的对象:

QML对象的QObject指针 字符串形式的属性 DB-key 作为字符串

?

最好的解决方案是,好像该属性连接到另一个属性:

Item myQmlProp: MyCppInst("myDBKey") 

编辑 目前有效的是这个解决方案:

Item 
   id:myqmlitem
   myQmlProp: MyCppInst("myDBKey","myQmlProp",myqmlitem) 

或者像这样:

Item 
   id:myqmlitem
   Component.onCompleted:
      MyCppPublisher.subscribe("myDBKey1","myQmlProp1",myqmlitem)
      MyCppPublisher.subscribe("myDBKey2","myQmlProp2",myqmlitem)  
   

与更可取的解决方案相比,我必须显式传递连接的属性名称和 QML 项目实例。但是没关系,非常感谢您的回答! 我曾希望使用 QML 的 this-Keyword,但了解到,它目前在 QML 中未定义:-(

【问题讨论】:

从 QML 传递到 C++ 或从 C++ 获取 QML 属性值? @MohammadKanan Qml 应该能够传递对对象和属性的引用并传递 C++ KeyValue 存储的标记。 C++ 应该能够设置该对象的属性 对象我想你的意思是QQuickItem,到目前为止我从未在QML中见过对象指针 @MohammadKanan QQuickItem 是 QObject 的子对象。每个 QML 项目最终都作为 Qt 中的 QObject 指针。 @MohammadKanan QtObject 是 QML 中的普通 QObject 【参考方案1】:

只需给对象一个 id 并将该 id 传递给函数,它将成为 C++ 端的 QObject *。然后您可以使用元系统按名称访问属性:

// qml
Item 
  id: someitem
  ...
  CppObj.cppFoo(someitem)


// c++
void cppFoo(QObject * obj) 
  ...obj->property("myDBKey")...

引用也可以,例如children[index]

【讨论】:

看起来不错,刚刚经过测试,它甚至可以像这样工作myprop:CppObj.cppFoo(someitem) 但是,我仍然必须提供 QML-item 的属性名称,所以 Cpp 知道要像这样更改哪个属性myprop:CppObj.cppFoo("myprop",someitem) 关注您建议明确传递的 id 是否可以在 QML 中提供?如果我尝试,我会在 C++ 中获得 0x0。由于我已将 QObject* 替换为 void* - 我得到了一个指针,但不知道是哪种类型。 如果只需要访问属性,具体类型无所谓,所有QObject派生的获取元数据,所以可以使用propety()setProperty()来访问属性不管是什么类型。 id 仅在 QML 和 QML 中有效。它是一个“特殊”属性,应该更多地被视为“编译时构造”。 @ValentinHeinitz,您还可以将“objectname”添加到您的 qml 项目中,该项目在 c++ 中可见。 objectname: "someitem"【参考方案2】:

您可以做的是一个仅将您的 dbkey 作为参数的函数,并返回一个 QObject* 公开一个带有 READ 函数和 NOTIFY 信号的 Q_PROPERTY

这样,你只需要用 notify 信号告知值已经改变,QML 就会自动调用 read 函数。

可以像Item myQmlProp: MyCppInst("myDBKey").value 那样实现。

如果您在编译时知道 db 键,您可以直接在 MyCppInst 中为每个键添加一个属性,或者如果您在创建 cpp 类时知道它们,您可以将它们放入 QQmlPropertyMap . 用法是这样的:Item myQmlProp: MyCppInst.myDbKey (或MyCppInst["myDbKey"],如果您需要在 QML 方面保持动态)。

【讨论】:

以上是关于将 QObject 指针从 QML 对象传递给 C++的主要内容,如果未能解决你的问题,请参考以下文章

如何将 QObject 指针的属性公开给 QML

如何将具有指向 QML 的指针成员的非 QObject 类公开?

C将int数组指针作为参数传递给函数

QML 未能检测到在 C++ 中破坏的 QObject

C ++将多个对象传递给线程中的函数

将 lambda 函数作为第三个参数传递给 QObject::connect 时出错