文档如是说,使用C ++代码中定义的功能可以轻松扩展QML。
由于QML引擎与Qt元对象系统的紧密集成,可以从QML代码访问由QObject派生的类适当公开的任何功能。
这使得C ++类的属性和方法可以直接从QML访问,通常很少或无需修改。
QML引擎能够通过元对象系统内省QObject实例。
这意味着,
通常,无论是否已向QML类型系统注册了QObject派生类,都可以从QML访问它们。
但是,如果QML引擎要访问其他类型信息(例如,如果要将类本身用作方法参数或属性,或者要将其中一个枚举类型用于以这种方式使用),那么该类可能需要注册。
颜色改变例子
新建一个ColorMaker类
colormaker.h文件如下:
#ifndef COLORMAKER_H
#define COLORMAKER_H
#include
#include
#include
class ColorMaker : public QObject
{
Q_OBJECT
Q_ENUMS(GenerateAlgorithm)
Q_PROPERTY(QColor color READ getColor WRITE setColor NOTIFY colorChanged)
Q_PROPERTY(QColor timeColor READ timeColor)
public:
explicit ColorMaker(QObject *parent = 0);
enum GenerateAlgorithm
{
RandomRGB,
RandomRed,
RandomBlue,
RandomGreen,
LinearIncrease
};
QColor getColor() const;
void setColor(const QColor &color);
QColor timeColor() const;
Q_INVOKABLE GenerateAlgorithm algorithm() const;
Q_INVOKABLE void setAlgorithm(GenerateAlgorithm algorithm);
signals:
void colorChanged(const QColor &color);
void currentTime(const QString &timeStr);
public slots:
void start();
void stop();
protected:
void timerEvent(QTimerEvent *e);
private:
GenerateAlgorithm m_algorithm;
QColor m_currentColor;
int m_nColorTimer;
};
#endif // COLORMAKER_H
colormaker.cpp文件
#include "colormaker.h"
#include
ColorMaker::ColorMaker(QObject *parent) : QObject(parent),
m_algorithm(RandomRGB),
m_currentColor(Qt::black),
m_nColorTimer(0)
{
qsrand(QDateTime::currentDateTime().toTime_t());
}
QColor ColorMaker::getColor() const
{
return m_currentColor;
}
void ColorMaker::setColor(const QColor &color)
{
m_currentColor = color;
}
QColor ColorMaker::timeColor() const
{
QTime time = QTime::currentTime();
int r = time.hour();
int g = time.minute();
int b = time.second();
return QColor::fromRgb(r, g, b);
}
ColorMaker::GenerateAlgorithm ColorMaker::algorithm() const
{
return m_algorithm;
}
void ColorMaker::setAlgorithm(GenerateAlgorithm algorithm)
{
m_algorithm = algorithm;
}
void ColorMaker::start()
{
if(m_nColorTimer == 0)
{
m_nColorTimer = startTimer(1000);
}
}
void ColorMaker::stop()
{
if(m_nColorTimer > 0) {
killTimer(m_nColorTimer);
m_nColorTimer = 0;
}
}
void ColorMaker::timerEvent(QTimerEvent *e)
{
if(e->timerId() == m_nColorTimer) {
switch (m_algorithm) {
case RandomRGB:
m_currentColor.setRgb(qrand() % 255,
qrand() % 255,
qrand() % 255
);
break;
case RandomRed:
m_currentColor.setRed(qrand() % 255
);
break;
case RandomGreen:
m_currentColor.setGreen(qrand() % 255
);
break;
case RandomBlue:
m_currentColor.setBlue(qrand() % 255
);
break;
case LinearIncrease:
int r = m_currentColor.red() + 10;
int g = m_currentColor.green() + 10;
int b = m_currentColor.blue() + 10;
m_currentColor.setRgb(r % 255, g % 255, b % 255);
break;
}
emit colorChanged(m_currentColor);
emit currentTime(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"));
}
else {
QObject::timerEvent(e);
}
}
在main.cpp文件中使用qmlRegisterType函数注册C++类型
int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
This template function registers the C++ type in the QML system with the name qmlName, in the library imported from uri having the version number composed from versionMajor and versionMinor.
这个模板函数注册C++类型,在QML系统中命名为qmlname,
在从uri导入的库,该库的版本数字由versionMajor和versionMinor组成(大版本及小版本,如:1.0, 1.1, …)
main.qml文件
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
import com.superyu.ColorMaker 1.0
Rectangle {
width: 400
height: 400
Text {
id: timeLabel
anchors.left: parent.left
anchors.leftMargin: 5
anchors.top: parent.top
anchors.topMargin: 5
font.pointSize: 26
}
ColorMaker {
id: colorMaker
color: "red"
}
Rectangle {
id: colorRect
anchors.centerIn: parent
width: 200
height: 200
color: "blue"
}
Button {
id: start
text: "Start"
anchors.left: parent.left
anchors.leftMargin: 5
anchors.bottom: parent.bottom
anchors.bottomMargin: 5
onClicked: {
colorMaker.start();
}
}
Button {
id: stop
text: "Stop"
anchors.left: start.right
anchors.leftMargin: 5
anchors.bottom: start.bottom
onClicked: {
colorMaker.stop();
}
}
function changeAlgorithm(button, algorithm) {
switch(algorithm)
{
case 0:
button.text = "RandomRGB";
break;
case 1:
button.text = "RandomRed";
break;
case 2:
button.text = "RandomGreen";
break;
case 3:
button.text = "RandomBlue";
break;
case 4:
button.text = "LinearIncrease";
break;
}
}
Button {
id: colorAlgorithm
text: "RandomRGB"
anchors.left: stop.right
anchors.leftMargin: 5
anchors.bottom: start.bottom
onClicked: {
var algorithm = (colorMaker.algorithm() + 1) % 5;
changeAlgorithm(colorAlgorithm, algorithm);
colorMaker.setAlgorithm(algorithm)
}
}
Button {
id: quit
text: "Quit"
anchors.left: colorAlgorithm.right
anchors.leftMargin: 5
anchors.bottom: start.bottom
onClicked: {
Qt.quit();
}
}
Component.onCompleted: {
colorMaker.color = Qt.rgba(0, 180, 120, 255);
colorMaker.setAlgorithm(colorMaker.LinearIncrease);
changeAlgorithm(colorAlgorithm, colorMaker.algorithm());
}
Connections {
target: colorMaker
onCurrentTime: {
timeLabel.text = timeStr;
timeLabel.color = colorMaker.timeColor;
}
}
Connections {
target: colorMaker
onColorChanged: {
colorRect.color = color;
}
}
}
import com.superyu.ColorMaker 1.0
这个导入库在main.cpp文件的qmlRegisterType(“com.superyu.ColorMaker”, 1, 0, “ColorMaker”);定义了
使用ColorMaker对象
ColorMaker {
id: colorMaker
color: "red"
}
点击colorAlgorithm按钮改变颜色显示算法
Button {
id: colorAlgorithm
text: "RandomRGB"
anchors.left: stop.right
anchors.leftMargin: 5
anchors.bottom: start.bottom
onClicked: {
var algorithm = (colorMaker.algorithm() + 1) % 5;
changeAlgorithm(colorAlgorithm, algorithm);
colorMaker.setAlgorithm(algorithm)
}
}
在组件加载完后,再改变颜色算法
Component.onCompleted: {
colorMaker.color = Qt.rgba(0, 180, 120, 255);
colorMaker.setAlgorithm(colorMaker.LinearIncrease);
changeAlgorithm(colorAlgorithm, colorMaker.algorithm());
}
连接信号到Qml
Connections {
target: colorMaker
onCurrentTime: {
timeLabel.text = timeStr;
timeLabel.color = colorMaker.timeColor;
}
}
Connections {
target: colorMaker
onColorChanged: {
colorRect.color = color;
}
}
//colorMaker.h
signals:
void colorChanged(const QColor &color);
void currentTime(const QString &timeStr);
更新事件及改变colorRect的颜色
1.创建一个父类为QObject的类;
2.将要曝光给QML的属性用Q_Property声明,如:Q_PROPERTY(QColor color READ getColor WRITE setColor NOTIFY colorChanged),函数用Q_INVOKABLE声明;
3.注册类型qmlRegisterType(“com.superyu.ColorMaker”, 1, 0, “ColorMaker”)
4.在qml文件中导入C++类,import com.superyu.ColorMaker 1.0
5.在qml文件中使用Connections,与C++类发送的信号相连
Connections {
target: colorMaker //连接对象
onColorChanged: { //信号槽函数
colorRect.color = color;
}
}
cppInvokeQml.qml
import QtQuick 2.0
Item {
id: root
width: 200
height: 200
//自定义属性,cpp可以访问
property string msg: "superyu"
//自定义信号,可以触发cpp槽函数
signal qmlSendMsg(string arg1, string arg2)
Rectangle {
anchors.fill: parent
color: "red"
objectName: "rect"
}
MouseArea {
anchors.fill: parent
onClicked: {
console.log("qml点击鼠标, 发送信号qmlSendMsg");
root.qmlSendMsg(root.msg, "myarg2");
}
}
onHeightChanged: console.log("qml height changed...");
onWidthChanged: console.log("qml width changed...");
//QML中的方法可以被cpp调用,也可以作为槽函数
function qmlMethod(var_arg)
{
console.log("qml method running", var_arg, "return ok");
return "ok";
}
function qmlRecvMsg(arg1, arg2)
{
console.log("qml slot running...", arg1, arg2);
}
}
自定义信号和属性,以便于cpp文件中使用
cppCallQml.h文件
#ifndef CPPCALLQML_H
#define CPPCALLQML_H
#include
#include
class CppCallQml : public QObject
{
Q_OBJECT
public:
explicit CppCallQml(QObject *parent = Q_NULLPTR);
signals:
//信号 --用来触发qml的函数
//注意参数为var类型,对应qml中js函数的参数类型
void cppSendMsg(const QVariant &arg1, const QVariant &arg2);
public slots:
void cppRecvMsg(const QString &arg1, const QString &arg2);
};
#endif // CPPCALLQML_H
cppCallQml.cpp文件
#include "cppcallqml.h"
CppCallQml::CppCallQml(QObject *parent) : QObject(parent)
{
}
void CppCallQml::cppRecvMsg(const QString &arg1, const QString &arg2)
{
qDebug()<< "CppObject::cppRecvMsg" << arg1 << arg2;
qDebug()<< "emit cppSendMsg";
emit cppSendMsg(arg1, arg2);
}
main.cpp文件
//c++调用qml
QQuickView view(QUrl("qrc:/cppInvokeQmlMain.qml"));
view.show();
//获取到qml跟对象的指针
QObject *qmlObj = view.rootObject();
QQmlProperty(qmlObj, "height").write(300);
qDebug()<< "cpp get qml property height: "
<< qmlObj->property("height");
qDebug()<< "cpp get qml property msg: "
<< qmlObj->property("msg");
//通过QQuickItem设置属性
QQuickItem *item = qobject_cast(qmlObj);
item->setWidth(300);
//查找子项
QObject *qmlRect = qmlObj->findChild("rect");
if(qmlRect) {
qDebug() << "cpp get rect color: " << qmlRect->property("color");
}
//调用qml方法
QVariant val_return;
QVariant val_arg = "superyu";
//Q_RETURN_ARG(),Q_ARG()参数必须为QVariant类型
QMetaObject::invokeMethod(qmlObj,
"qmlMethod",
Q_RETURN_ARG(QVariant, val_return),
Q_ARG(QVariant, val_arg));
qDebug() << "QMetaObject::invokeMethod result: " << val_return;
//关联信号槽
CppCallQml cppObj;
QObject::connect(
qmlObj,
SIGNAL(qmlSendMsg(QString, QString)),
&cppObj,
SLOT(cppRecvMsg(QString, QString))
);
QObject::connect(
&cppObj,
SIGNAL(cppSendMsg(QVariant, QVariant)),
qmlObj,
SLOT(qmlRecvMsg(QVariant, QVariant))
);
return app.exec();
QML__Nokia内部培训资料(1).pdf
https://blog.csdn.net/gongjianbo1992/article/details/87965925
https://github.com/gongjianbo/MyTestCode/tree/master/Qml/CppCallQml2020