一、结语
在QtQuick合作开发中,QML插件一般来说须要用C++来处置高阶和操控性专门化的各项任务。为的是与此同时实现这一点儿,最常用、最快捷的方式是:向QML运转时自然环境申明C++类(特别注意:该C++类要衍生自QObject),在Qt 5.7或更高版中,责任编辑将叙述下列三个难题:
(1)怎样在QML插件中采用C++类。
(2)向QML导出C++方式(主要包括槽表达式)
二、怎样在QML插件中采用C++类
(2-1)建立三个C++类:class Datas
//datas.h 子程序
#ifndef DATAS_H
#define DATAS_H
#include <QObject>
#include <QString>
class Datas : public QObject
{
Q_OBJECT
Q_PROPERTY(QString m_age READ getAge WRITE setAge NOTIFY ageChanged)
public:
explicit Datas(QObject *parent = nullptr);
QString getAge(){
return m_age;
}
void setAge(const QString &age)
{
m_age = age;
emit ageChanged();
}
signals:
void ageChanged();
private:
QString m_age;
};
#endif // DATAS_H
//datas.cpp
#include “datas.h”
Datas::Datas(QObject *parent) : QObject(parent),
m_age(“25”)
{
}
前述标识符中,在C++类中采用Q_PROPERTY宏新闻稿了三个能从QML出访的特性,这儿是m_age特性;并新闻稿了读、写该特性的方式:getAge()和setAge();与此同时新闻稿了该特性发生改变而所收到的讯号:ageChanged():
Q_PROPERTY(QString m_age READ getAge WRITE setAge NOTIFY ageChanged)
(2-2)注册登记C++类
在前述关键步骤中,他们表述了三个C++类,为的是在QML自然环境中采用此类,须要将它注册登记到QML上下文自然环境中:
//main.c
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <datas.h>
int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
Datas m_datas;
QQmlContext *qmlctx = engine.rootContext();
qmlctx->setContextProperty(“cpp_datas”,&m_datas);
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);
return app.exec();
}
采用QQmlContex的setContextProperty()成员表达式向QML运转上下文自然环境注册登记C++类型,如下:
Datas m_datas;
QQmlContext *qmlctx = engine.rootContext();
qmlctx->setContextProperty(“cpp_datas”,&m_datas); //注册登记m_datas
(2-3)在QML中采用C++类中新闻稿的数据。
在main.c文件中,他们已经将Datas类的实例m_datas注册登记到到了QML运转上下文自然环境中,接下来,他们则能在QML中采用此类中新闻稿的数据了:
//main.qml文件
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
Window {
id: window
width: 640
height: 480
visible: true
color: “#117c90”
title: qsTr(“演示 | Author:iriczhao”)
Button {
id: button
x: 270
y: 345
text: qsTr(“Click”)
onClicked:
{
label.text = cpp_datas.m_age;
}
}
Label {
id: label
x: 168
y: 134
width: 305
height: 45
color: “#ffffff”
text: qsTr(“iriczhao”)
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.bold: true
}
}
如上标识符所示,在应用中放置了三个Button和Label,当点击Button后,Label标签的文本特性将被C++类中的m_age赋值。即应用界面将显示25。
(2-4)效果
请添加图片叙述三、向QML导出C++方式(主要包括槽表达式)
在上文中,叙述了怎样向QML申明C++类的数据特性。那么对于C++类的方式同样也能申明给QML。具体关键步骤如下:
(3-1)新闻稿C++成员表达式
对于QObject衍生类型的所有方式都能从QML标识符中出访。例如:
(1)采用“`Q_INVOKABLE“宏标记的公共方式。
(2)Qt C++公共槽表达式。
如下标识符片段:
class MessageBoard : public QObject{
Q_OBJECT
public:
Q_INVOKABLE bool postMessage(const QString &msg) {
qDebug() << “Called the C++ method with” << msg;
return true;
}
public slots:
void refresh() {
qDebug() << “Called the C++ slot”;
}
};
postMessage()表达式采用Q_INVOKABLE标记;refresh()表达式是三个公共槽表达式,所以这三个表达式都能从QML中出访。
(3-2)注册登记C++类
同样的,为的是采用C++类中的方式(主要包括槽表达式),须要将C++类注册登记到QML上下文自然环境中(这儿是MessageBoard类):
MessageBoard msgBoard; //实例MessageBoard
view.engine()->rootContext()->setContextProperty(“cpp_msgBoard”, &msgBoard); //将msgBoard注册登记到QML上下文自然环境中
(3-3)在QML中采用C++类的方式
如下标识符片段:
import QtQuick 2.0
Item {
width: 100; height: 100
MouseArea {
anchors.fill: parent
onClicked: {
var result = msgBoard.postMessage(“Hello from QML”)
console.log(“Result of postMessage():”, result)
msgBoard.refresh();
}
}
前述标识符中,采用msgBoard调用postMessage()和refresh()方式出访到了C++类中的方式。
四、归纳
(1)如果须要在QML中出访C++类中的数据成员。须要采用Q_PROPERTY新闻稿该数据成员,并新闻稿对数据成员的读、写表达式以及数据发生改变时的关联讯号。
然后采用QQmlContex的setContextProperty()将C++类注册登记到QML上下文中。
(2)如果须要在QML中出访C++方式(主要包括槽表达式),这儿分为两种情况:
如果该表达式是三个公共表达式,他们须要采用Q_INVOKABLE宏去标记它。如果是三个公共的槽表达式,则能直接出访。同样的,采用QQmlContex的setContextProperty()将C++类注册登记到QML上下文中。