思路:
自己写一个c++ 类, 将c++注册到qml 中, 作为qml的一种类型
具体划分:有三种交互方式:
1:封装的class 以信号槽的形式和 qml 交互
2: 封装的class 以函数的形式和 qml 交互
3: 封装的class 以属性值得形式和 qml 交互
代码连接:
https://gitee.com/kamenqing/qml-and-c-interaction.git
以信号槽的形式和 qml 交互:Demon 例子: qml_1 文件夹
1> 定义一个 c++ 类 (widget.h 文件中)
class widget : public QObject
{
Q_OBJECT
public:
// 构造函数
widget(){
qDebug()<<"widget 构造函数初始化 ...";
}
signals:
// 发送信号
void sig_send();
public slots:
// 接受槽函数
void slot_recive();
};
2> 注册 widget 类为Qt的元对象 提供给qml ( main.cpp 中) 代码 第 10行:
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
// 注册 widget 到Qt 元对象中 提供qml 使用
//Moudle.widge: 模块名 1, 0 : 版本
// Widget:在qml 中的类型。 这个任意写都可以,只要确保qml 中一致就可以
qmlRegisterType<widget>("Moudle.widget", 1, 0, "Widget");
QQmlApplicationEngine engine;
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();
}
3> qml 中 调用 widget 类: 代码在main.qml 中
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Rectangle
{
anchors.fill: parent
color: "red"
MouseArea
{
anchors.fill: parent
// 鼠标点击 触发 widget 的信号
onClicked: hwidget.sig_send()
}
}
// 对应 c++ widget 类 做为qml 中的类型调用
Widget
{
id: hwidget // id 也可以认为是 widget 类型的别名
// 信号接受,on+信号名称, 第一个字母大写
onSig_send: slot_recive()
}
}
二: 以函数的形式和 qml 交互:Demon 例子: qml2 文件夹
1>: 定义一个 c++ 类 (widget.h 文件中)
class widget : public QObject
{
Q_OBJECT
public:
// 构造函数
widget(){
qDebug()<<"widget 构造函数初始化 ...";
}
// 普通函数 使用 Q_INVOKABLE 宏
Q_INVOKABLE void function(int num);
Q_INVOKABLE QString function1(QString str);
};
2>:注册 widget 类为Qt的元对象 提供给qml ( main.cpp 中) 代码 和上面的第二部一样
3>: qml 中 调用 widget 类: 代码在main.qml 中
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Rectangle
{
anchors.fill: parent
color: "red"
Text {
id: name
text: qsTr("text")
anchors.centerIn: parent
font.pixelSize: 14
}
MouseArea
{
anchors.fill: parent
// 鼠标点击 触发 widget 的信号
onClicked:
{
// 调用 function 带有参数
hwidget.function(123)
// 调用 function1 带有参数 以及返回值, 返回给 text 并显示
name.text = hwidget.function1("黑塞")
}
}
}
Widget
{
id: hwidget // id 也可以认为是 widget 类型的别名
}
}
三: 以属性值得形式和 qml 交互:Demon 例子: qml3文件夹
1>: 定义一个 c++ 类 (widget.h 文件中)
class widget : public QObject
{
Q_OBJECT
public:
// 构造函数
widget(){
qDebug()<<"widget 构造函数初始化 ...";
}
//unsigned int number: qml 中调用的属性值, hwidget.number
//READ num : 当qml 获取 number 的时候 就会调用 num 函数
//WRITE setnum : 当qml 设置 number 的时候 就会调用 setnum 函数
// NOTIFY numchange: 与属性关联的可选信号。这个信号必须在类中声明过,当属性值改变时,就可触发这个信号,可以没有参数,有参数的话只能是一个类型同属性本身类型的参数,用来记录属性改变后的值。
// 获取 类成员 属性值
Q_PROPERTY(unsigned int number READ num WRITE setnum NOTIFY numchange);
int m_num =10;
int num()
{
qDebug()<<"获取属性 num:"<<m_num;
return m_num;
}
void setnum(int number)
{
qDebug()<<"设置 属性 num :" << number;
m_num = number;
emit numchange(number);
}
signals:
void numchange(int);
};
2>:注册 widget 类为Qt的元对象 提供给qml ( main.cpp 中) 和上面的第二部一样
3>: qml 中 调用 widget 类: 代码在main.qml 中
核心代码:
MouseArea
{
anchors.fill: parent
// 鼠标点击 触发 widget 的信号
onClicked:
{
// hwidget.number 就会调用 num 函数
console.log(hwidget.number)
// 赋值hwidget.number 会调用 setnum 函数。
hwidget.number = 1000;
}
}
Widget
{
id: hwidget // id 也可以认为是 widget 类型的别名
// 对应 number 变化,调用 numchange 信号处理函数
onNumchange: console.log(hwidget.number)
}
}