问题
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 inmain.cpp
before you create the QML application, then you can access it from insideMyQuickItem
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