Author: Lao Jiu – technology big millet
Socializing: Zhihu
Public account: Lao Jiu School (Surprise for newcomers)
Special statement: the original is not easy, without authorization shall not be reproduced or copied, if you need to reproduce can contact the author authorized
preface
This handout code is implemented using Qt 6 version, please rest assured to use.
What is the QML
Let me translate it for you.
QML is an abbreviation of Qt Meta-Object Language. It is a declarative programming language, and it is part of the Qt framework. The main function of QML is to allow developers to quickly and easily develop user interfaces for desktop applications, mobile devices, and embedded applications. Moreover, QML can be developed and used seamlessly with JavaScript, meaning that JavaScript files can be used directly within QML code.
The first Hello World
import QtQuick 2.9
import QtQuick.Window 2.2
Window{
visible:true
width:640
height:480
title:qsTr("Hell World");
Rectangle {
width: 360
height: 360
Rectangle{
id: button1
width: 100
height: 30
color: "red"
radius: 5
anchors.centerIn:parent
Text{
id: buttonText
text:qsTr("Button")
color:"white"
anchors.centerIn:parent
}
MouseArea{
anchors.fill:parent
onClicked:{
buttonText.text = qsTr("Clicked");
buttonText.color = "black";
}
}
}
}
Text{
id:text1
text: qsTr("Hello World")
anchors.left:button1.right
}
Image{
source:"nb.png"
anchors.centerIn:parent
}
}
Copy the code
Running effect
Mouse event response
import QtQuick 2.9
import QtQuick.Window 2.2
Window{
visible:true
width:480
height:240
Rectangle{
anchors.fill:parent
color:"#4b7a4a"
MouseArea{
anchors.fill:parent
acceptedButtons: Qt.AllButtons
onClicked: {console.log("Mouse Clicked.")
console.log("Mouse Location: <",mouseX,",",mouseY,">").
if ( mouse.button === Qt.RightButton )
parent.color = 'blue'
if ( mouse.button === Qt.LeftButton )
parent.color = 'red'
if ( mouse.button === Qt.MiddleButton )
parent.color = 'yellow'
}
onReleased: {
// print to console
console.log("Mouse Released.")}onDoubleClicked: {
// print to console
console.log("Mouse Double Clicked.")}}}}Copy the code
Running effect
animation
Demo code
import QtQuick 2.9
import QtQuick.Window 2.2
Window{
visible: true
width: 400
height: 640
Rectangle{
id: rect
anchors.centerIn: parent
height: 100
width: 100
color: "blue"
MouseArea{
anchors.fill: parent
onClicked: na.running = true
}
NumberAnimation {
id: na // The ID of the animation type
target: rect // The target item for the animation to run
property: "height" // What are the attributes of the target item for animation modification
duration: 200 // The length of animation execution time
from: rect.height // The initial value of the animation property
to: 200 // The final value of the property after animation execution}}}Copy the code
Running effect
We click on the blue square
Create custom elements in C++
QML has a large number of visual elements, and it is possible to build complex applications with QML visual elements if you only use the QML scripting language. We can build interfaces based on these standard widgets, and we can also use Canvas elements to create custom elements. All QML interface elements can be constructed, except for touch elements.
However, QML scripts are not a panacea, although QML can be used to implement two types of custom drawing elements because of OpenGL technology:
- The traditional for Qt way using QPainter (QQuickPaintedItem). (The traditional way is to use QPainter/QQuickPaintedItem to map interface)
- The common QML way using QQuickItem and OpenGL functionality. The common QML way using QQuickItem and OpenGL functionality.
The first approach seems easy to implement, and QtQuick is slow to draw efficiently, so interface elements run faster if we use the second approach.
Demo code
QQuickCustomItem header file
#pragma once
#include <QQuickItem>
/** * create a custom class that implements the QQuickItem class. Used to demonstrate the implementation of custom control elements
class QQuickCustomItem :
public QQuickItem
{
Q_OBJECT
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
public:
QQuickCustomItem(QQuickItem* parent = Q_NULLPTR);
void paint(QPainter* painter);
protected:
QSGNode* updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData* updatePaintNodeData);
QColor color(a) const;
void setColor(const QColor& color);
private:
QColor m_color;
bool m_needUpdate;
signals:
void colorChanged(a);
};
Copy the code
QQuickCustomItem source file
#include "QQuickCustomItem.h"
#include <QSGGeometryNode>
#include <QSGFlatColorMaterial>
#include <QPainterPath>
#include <QPainter>
QQuickCustomItem::QQuickCustomItem(QQuickItem* parent /*= Q_NULLPTR*/)
:QQuickItem(parent),
m_color(Qt::red),
m_needUpdate(true)
{
setFlag(QQuickItem::ItemHasContents);
}
void QQuickCustomItem::paint(QPainter* painter)
{
QPainterPath path;
path.moveTo(width(a) /2.0);
path.lineTo(width(), height());
path.lineTo(0.height());
path.lineTo(width(a) /2.0);
painter->fillPath(path, m_color);
}
QSGNode* QQuickCustomItem::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData* updatePaintNodeData)
{
Q_UNUSED(updatePaintNodeData)
QSGGeometryNode* root = static_cast<QSGGeometryNode*>(oldNode);
if(! root) { root =new QSGGeometryNode;
QSGGeometry* geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 3);
geometry->setDrawingMode(6);
geometry->vertexDataAsPoint2D(to)0].set(width(a) /2.0);
geometry->vertexDataAsPoint2D(to)1].set(width(), height());
geometry->vertexDataAsPoint2D(to)2].set(0.height());
root->setGeometry(geometry);
root->setFlag(QSGNode::OwnsGeometry);
root->setFlag(QSGNode::OwnsMaterial);
}
if (m_needUpdate) {
QSGFlatColorMaterial* material = new QSGFlatColorMaterial;
material->setColor(m_color);
root->setMaterial(material);
m_needUpdate = false;
}
return root;
}
QColor QQuickCustomItem::color(a) const
{
return m_color;
}
void QQuickCustomItem::setColor(const QColor& color)
{
if(m_color ! = color) { m_color = color; m_needUpdate =true;
update(a);colorChanged();
}
}
Copy the code
The main QML file
import QtQuick 2.3
import QtQuick.Window 2.2
import main.qml 1.0
Window {
width: 800
height: 800
visible: true
Rectangle {
width: 200
height: 200
anchors.centerIn: parent
color: "lightgrey"
Triangle {
id: rect
width: 200
height: 200
transformOrigin: Item.Top
color: "green"
onColorChanged: console.log("color was changed");
PropertyAnimation on rotation {
from: 0
to: 360
duration: 5000
loops: Animation.Infinite
}
}
}
Timer {
interval: 1000
repeat: true
running: true
onTriggered: rect.color = Qt.rgba(Math.random(),Math.random(),Math.random(),1); }}Copy the code
The main CPP file
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "QQuickCustomItem.h"
int main(int argc, char *argv[])
{
#if defined(Q_OS_WIN)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QGuiApplication app(argc, argv);
// Technology: use custom components to display triangle animation
qmlRegisterType<QQuickCustomItem>("main.qml".1.0."Triangle");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return - 1;
return app.exec(a); }Copy the code
Running effect
With c + + integration
We can create QtQuick views directly from C++, and we can also expose C++ defined functions to QML.
The main CPP file
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "QQuickCustomItem.h"
#include <QQuickView>
#include <QQmlContext>
int main(int argc, char *argv[])
{#if defined(Q_OS_WIN)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QGuiApplication app(argc, argv);
QQuickView view;
view.setSource(QStringLiteral("main.qml"));
// Retrieving the QML context. This context allows us to expose data to the QML components
QQmlContext* rootContext = view.rootContext();
// Creating 2 new properties: the width and height of the view
rootContext->setContextProperty("WINDOW_WIDTH".640);
rootContext->setContextProperty("WINDOW_HEIGHT".360);
// Let's display the view
view.show();
return app.exec();
}
Copy the code
The main QML file
import QtQuick 2.3
Rectangle {
// We can now access the properties we defined from C++ from the whole QML file
width: WINDOW_WIDTH
height: WINDOW_HEIGHT
Text {
text: qsTr("Hello World")
anchors.centerIn: parent
}
}
Copy the code
Running effect
Qt5 version updated
For qT5.x, we can replace the QQuickView class with the QQmlApplicationEngine class to load and render QML scripts. Modify the code as follows:
Modify the main CPP
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "QQuickCustomItem.h"
#include <QQuickView>
#include <QQmlContext>
int main(int argc, char *argv[])
{
#if defined(Q_OS_WIN)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
QQmlContext* rootContext = engine.rootContext(a); rootContext->setContextProperty("WINDOW_WIDTH".640);
rootContext->setContextProperty("WINDOW_HEIGHT".360);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec(a); }Copy the code
Modify the main QML
import QtQuick 2.3
import QtQuick.Window 2.2
Window { // Must be this type to be loaded by QQmlApplicationEngine.
visible: true
width: WINDOW_WIDTH //Accessing global context declared in C++
height: WINDOW_HEIGHT //Accessing global context declared in C++
title: qsTr("Hello World")
Component.onCompleted: {
// We can access global context from within JavaScript too.
console.debug( "Width: " + WINDOW_WIDTH )
console.debug( "Height: " + WINDOW_HEIGHT )
}
MouseArea {
anchors.fill: parent
onClicked: {
Qt.quit();
}
}
Text {
text: qsTr("Hello World! and click here to quit the programm.")
anchors.centerIn: parent
}
}
Copy the code
Running effect
The last
Remember to give dashu ❤️ attention + like + collect + comment + forward ❤️
Author: Lao Jiu School – technology big millet
Copyright belongs to the author. Commercial reprint please contact the author for authorization, non-commercial reprint please indicate the source.