1. First look at the demo
The project automatically generated by QtCreator uses QQmlApplicationEngine to load qml files, and the following demo will use QQuickView to load qml files
#include <QGuiApplication>
#include <QtQuick/QQuickView>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQuickView view;
view.setSource(QUrl(QLatin1String("qrc:/main.qml")));
view.setTitle("Hello World");
view.show();
return app.exec();
}
Are the two interface functions setTitle() and show() familiar? Yes, the usage methods of QQuickView and QWindow are very similar. In fact, QQuickView inherits from QQuickWindow, and QQuickWindow inherits from QWindow
QQuickView loads qml files using the interface function: setSource()
2. Window elements are not displayed in QQuickView
After modifying mian.cpp, there is a window when running directly, but the size and title are not set by the Windowu element in the qml file.
The reason is: the Window element is not displayed in QQuickView.
The qml file needs to be modified. The modified qml file is as follows:
import QtQuick 2.15
Rectangle {
id: rect
width: 640;
height: 480
color: "red"
}
The running effect is as follows:
3. The Window element must be used in the QQmlApplicationEngine
QQuickView will automatically create a root window, and QQmlApplicationEngine will not automatically create a root window, so you need to use the Window object to create a new top-level window for the Qt Quick scene in the root qml file loaded with QQmlApplicationEngine. At this point, QML has complete control over the window, and can directly set properties such as title and window size.
4. The difference between QQuickWidget and QQuickView
QQuickWidget inherits from QWidget and can be directly added to Qt layout;
QQuickView inherits from QQuickWindow (inherited from QWindow), and can be added to Qt layout only through conversion:
QQuickView *view = new QQuickView();
QWidget *widget = QWidget::createWindowContainer(view, this);
view->setSource(QUrl("qrc:/main.qml"));
5. Using C++ in QML
5.1 Defining C++ classes
To call C++ classes in QML, the definition of C++ classes has certain requirements
1) Declaration: Q_OBJECT
QML uses Qt's meta-object system, so it needs to be declared at the beginning of the class: Q_OBJECT
2) Modified function: Q_INVOKABLE
Use the Q_INVOKABLE modified member function to be recognized by the Qt meta-object system;
otherwise, an error will be reported when calling the member function
TypeError: Property 'xxx' of object xxx is not a function
3) Modify the enumeration: Q_ENUMS
Use the enumeration modified by Q_ENUMS to be recognized by the Qt meta-object system;
4) Define property: Q_PROPERTY
Q_PROPERTY(type name
READ getFunction
[WRITE setFunction]
[RESET resetFunction]
[NOTIFY notifySignal]
[DESIGNABLE bool]
[SCRIPTABLE bool]
[STORED bool]
[USER bool]
[CONSTANT]
[FINAL])
例如:Q_PROPERTY(double testValue READ getTestValue WRITE setTestValue)
5) In this example, only the usage of Q_INVOKABLE is shown
class Class2Qml : public QObject
{
Q_OBJECT
public:
explicit Class2Qml(QObject *parent = nullptr);
Q_INVOKABLE void call(const QString &msg);
};
void Class2Qml::call(const QString &msg)
{
qDebug() << "Class2Qml, msg = " << msg;
}
5.2 Introducing C++ classes into QML
Use QQuickView::rootContext()->setContextProperty to introduce C++ classes into QML
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
Class2Qml c2q;
QQuickView view;
view.setSource(QUrl(QLatin1String("qrc:/quickView.qml")));
view.setTitle("Hello World");
view.setResizeMode(QQuickView::SizeRootObjectToView);
view.rootContext()->setContextProperty("c2q", &c2q);
view.show();
return app.exec();
}
5.3 Using C++ classes in QML
In QML, it can be called by using the format of == class name. member function name (parameter) ==. The complete QML code is as follows
import QtQuick 2.15
import QtQuick.Controls 2.15
Rectangle {
id: rect
width: 640;
height: 480
color: "red"
Button {
id: btn1
width: 50
height: 50
x:100
y:100
text:"msg"
onClicked: {
c2q.call("quickView Rectangle")
}
}
}