qt – 在QML​​中创建自定义C对象并将其存储在C模型中

我在C中编写了一个客户类(继承自QObject),并使用QML成功注册了它的类型.目前我正在C中静态创建此类的对象,并在实现QAbstractListModel的Model中存储指向它们的指针.在QML中,我可以完美地访问对象作为模型的项目.

customObject是一个非可视对象.

我在GUI应用程序的另一部分(QML)中使用委托可视化ListView中的对象.

但是现在我想在QML中动态地从我的自定义类创建对象,并将它们也存储在模型中.这是我在努力的地方.我希望我可以像这样创建一个customObject:

import com.myProject.myCustomStuff 1.0

...


Button{
   id: createObjBtn
   text: "create new CustomObj"
   onClicked:{
      var obj = MyCustomObj;
      myObjectManager.addObj(obj);  // object holding the implemented QAbstactListModel
      console.log(typeof(obj)); // returns [Object object]
      console.log(Qt.isQtObject(obj)) // returns false
   }
}

我很感激你的想法.也许有人知道如何正确地做到这一点?

谢谢!

更新1

根据Simon-Warta的要求,这是MyCustomObj的构造函数实现.

MyCustomObj.cpp

MyCustomObj::MyCustomObj(QObject *parent) : QObject(parent)
{
    QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
}

最佳答案 您混淆了类的功能意图. QAbstractListModel旨在作为容器的包装器,是的,你可以将容器放在QAbstractListModel派生类中,但你真的不必,容器可以只是任何C类,甚至不一定是QObject派生的,它可以只是一个QVector< Something>您可以通过指针从模型到达.这对于你有很多物体的情况很有用,并且并非所有物体都需要随时都有模型,因为这些模型非常重.

你真的不需要关心自己的所有权,把它放在C端,同样适用于实际的对象创建,有一个叫做的插槽,它将新对象添加到容器中,同时还使用模型的beginInsertRows()和endInsertRows()以便通知任何视图有效更新,新对象也应该在该槽中创建,你可以从QML传递它所需的任何数据,只需确保所有数据都注册到Qt元系统,这样它可以使用QVariant进行QML-C互操作.

所以它应该是这样的:

myObjectManager.create(/* any needed data goes here */)

create()将最终数据传递给C端,在那里创建对象,调用beginInsertRows(),将对象添加到模型的底层存储中,然后调用endInsertRows()并完成.

我更愿意将所有权保留在C方面(我并不是明确表示),我可以控制它.在处理C和QML之间共享的对象所有权时,Qt有点糟糕.理想情况下,应该有一个单独的共享指针类可以跨C和QML工作,因此一旦对它的所有引用都消失,该对象就会被删除.但这不是“Qt方式” – Qt共享指针不适用于QML,标准C共享指针也没有,实际上有一个完全不同的QML共享引用类,它甚至不是公共API的一部分IIRC,非常丑陋和短视的设计,只会扩大C和QML之间的差距以及相关的不便因素.

点赞