How to set a pure C++ object instance in a QQuickItem [duplicate]

只愿长相守 提交于 2019-12-13 09:01:20

问题


I have QtApp & a pure C++ library. The C++ library exposes a one simple class called MyCppLibApiClass. The QtApp has a class which is embedded on main.qml. Following is the class:

class MyQuickItem : public QQuickItem {
  MyQuickItem();
}

Following the qml code for the quick item:

import MyQuickItem 1.0

MyQuickItem {
  id: myQuickItemID
  visible: true
  objectName: "myQuickItem"
}

Following is my main.cpp showing I load the qml item:

qmlRegisterType<MyQuickItem>("MyQuickItem", 1, 0, "MyQuickItem");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
return app.exec();

MyQuickItem needs access to MyCppLibApiClass instance. How do a I get a valid instance to MyQuickItem in main.cpp ? I need to set an object of MyCppLibApiClass as member in MyQuickItem. I can do this using a setter method. But, first of all I need to get a valid instance to MyQuickItem. So How to get access to MyQuickItem in main.cpp ?

I have searched quite a before asking this question. I read through this link. Also, This question posted by me, did not get me an accurate answer. Hence, rephrasing my question more clearly to try get an answer. Appreciate suggestions to this..


回答1:


If you have a single instance of your library object, there are two ways you can go about it depending on what kind of access you need:

  • have the instance as a static member of the MyQuickItem class, initialize it in main.cpp before you create the QML application, then you can access it from inside MyQuickItem in C++.

  • have the instance inherit QObject and expose it as a context property, this way it can be accessed from QML.

If it is not a singleton object, you have two courses of action:

  • create the QML object from C++, it will give you direct pointer to it
  • find the QML object in the object tree by using QQmlApplicationEngine::rootObjects().at(0).findChild() for the type and object name, if found you will have a pointer to the object

However, as one of the answers of the questions you have liked suggests, this is not really considered recommended practice. There is probably a better way to do that, you shouldn't be doing setting QML object properties in main.cpp, it should be either in the constructor or public interface of MyQuickItem.




回答2:


in your main.cpp:

qmlRegisterType<MyQuickItem>("MyQuickItem", 1, 0, "MyQuickItem");
QQmlApplicationEngine engine;
MyQuickItem myItem;
engine.rootContext()->setContextProperty("myItem", &myItem);
engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));

Now you can access myItem from C++ and access that same myItem from QML, simply by setting the property "myItem" on the root level of the QML context to be a reference to your custom object.

EDIT

I added the qmlRegisterType declaration to the answer.

As per request in comment:

Using qmlRegisterType<>() is used to register a specific type in QML which can then be created/accessed from QML.

By using the engine.rootContext()->setContextProperty("myItem", &myItem) method you are actually creating myItem in C++ and setting the ownership of myItem to C++

Since QML is designed to work with C++, it is possible to simply assign myItem as a property in QML and since QML automatically inherits properties/objects from parent objects, then myItem becomes available in the entire QML context.

Neither of the two examples have been tested, and are simply to demonstrate the idea

Example main.qml

import MyQuickItem 1.0

Item {
   Component.onCompleted {
        myItem.visible = true;
        myItem.myCustomMethod();
   }
}

Example C++ Class

class MyQuickItem : public QQuickItem {


     MyQuickItem();

 public slots: 
    void myCustomMethod() { /* do some C++ stuff here */ }

 }


来源:https://stackoverflow.com/questions/40195129/how-to-set-a-pure-c-object-instance-in-a-qquickitem

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!