QT study notes of QML and C++ (on)
table of Contents
QT study notes of QML and C++ (on)
C++ object registration to the meta object system
Register the C++ class to the Qml system
Qml calls C++ object public functions
Qml access to C++ object properties (object member variables)
C++ object registration to the meta object system
- Use Q_INVOKABLE to declare, this macro declares the function as a function callable by the meta-object system. QtQuick is also in the meta-object system, so this function can also be accessed.
class TestCpp : public QObject { Q_OBJECT public: explicit TestCpp(QObject *parent = nullptr); Q_INVOKABLE void setNumber(int number); Q_INVOKABLE void getNumber(); private: int m_iNumber{}; signals: };
- achieve
void TestCpp::setNumber(int number) { m_iNumber = number; } int TestCpp::getNumber() { return m_iNumber; }
- Register the TestCpp class in QML
- ①Add header file (in main.cpp file)
#include <QQmlContext> #include "testcpp.h"
- ② Instantiate the object and register it (in the main.cpp file)
QQmlApplicationEngine engine; //添加如下代码 TestCpp testObj; testObj.setNumber(12345); engine.rootContext()->setContextProperty("testObj", &testObj);
- ③ Use it in the Qml file (in the main.qml file)
import QtQuick 2.12 import QtQuick.Controls 2.5 ApplicationWindow { visible: true width: 640 height: 480 title: qsTr("QmlTest") Button{ id: btn1 width: 120 height: 50 anchors.centerIn: parent onClicked: text = testObj.getNumber(); } Button{ id: btn2 width: 120 height: 50 anchors.top: btn1.bottom anchors.margins: 15 anchors.horizontalCenter: btn1.horizontalCenter onClicked: text = testObj.setNumber(67890); } }
- effect
Register the C++ class to the Qml system
- qmlRegisterType Registers C++ classes: When registering on the C++ side, the C++ classes are not instantiated, and the instantiation is done on the Qml side.
template<typename T> int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName); template<typename T, int metaObjectRevision> int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *
- Usage example: refer to https://doc.qt.io/qt-5/qqmlengine.html#qmlRegisterType
- For example, this registers a C++ class
MySliderItem
as a QML type namedSlider
for version 1.0 of a type namespace called "com.mycompany.qmlcomponents":qmlRegisterType<MySliderItem>("com.mycompany.qmlcomponents", 1, 0, "Slider");
- use
import com.mycompany.qmlcomponents 1.0 Slider { // ... }
【Exercise example】
- main.qml file
C++ create/get Qml object
- Can refer to: https://blog.csdn.net/xiezhongyuan07/article/details/109318209
- ① Create a new Qml file named TestQml.qml
- Code
import QtQuick 2.12 import QtQuick.Controls 2.5 import QtQuick.Window 2.2 Window { width: 300 height: 300 color: "pink" }
- ② main.cpp add
//添加头文件 #include <QQmlComponent> //添加代码 /*const QUrl url(QStringLiteral("qrc:/main.qml")); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.load(url);*/ QQmlComponent qmlComponent(&engine); qmlComponent.loadUrl(QUrl(QStringLiteral("qrc:/TestQml.qml"))); QObject* qmlTest = qmlComponent.create(); qmlTest->setParent(engine.rootObjects()[0]); engine.rootContext()->setContextProperty("qmlTest", qmlTest);
- ③ main.qml add
ApplicationWindow { visible: true width: 640 height: 480 title: qsTr("QmlTest") Button{ id: btn1 width: 120 height: 50 anchors.centerIn: parent onClicked: { qmlTest.visible = true; qmlTest.color = "green" } } Button{ id: btn2 width: 120 height: 50 anchors.top: btn1.bottom anchors.margins: 15 anchors.horizontalCenter: btn1.horizontalCenter onClicked:{ qmlTest.color = "blue" qmlTest.visible = true; } } }
- Modify TestQml.qml and add a rectangle inside the form
- main.cpp, find the object of the child form through findChild
QObject *qmlRect = qmlTest->findChild<QObject*>("rectangle"); qmlRect->setProperty("color", "pink");
- effect:
Qml calls C++ object public functions
- C++ Q_INVOKABL registered function.
Qml access to C++ object properties (object member variables)
- Use Q_PROPERTY
Q_PROPERTY(int number READ getNumber WRITE setNumber NOTIFY numberChanged)
- In testcpp.h
- Pay attention to the position of the code (the line below Q_OBJECT), and then add a signal, when the attribute change is triggered, the signal is numberChanged
- Register in main.cpp
QQmlApplicationEngine engine; //添加如下代码 TestCpp testObj; testObj.setNumber(12345); engine.rootContext()->setContextProperty("testObj", &testObj);
- main.qml add
Qml calls C++ object slot functions
public slots: void setNumber(int number);
void TestCpp::setNumber(int number) { m_iNumber += number; }
- Qml can directly call the slot function, because the slot function is originally in the meta-object system, and the C++ class has been registered in the meta-object system.