首页 > 编程语言 >Qml调用C++方法初探

Qml调用C++方法初探

时间:2023-02-04 15:14:42浏览次数:50  
标签:widget QmlControl int QQuickWidget C++ qml 初探 Qml

为什么会在QML中调用C++方法?
引入Qml的一个重要目的就是UI和逻辑的解耦,我们可以把业务逻辑用C++实现,Qml只用来开发界面,这样在后续程序改版过程中,基本上可以不动逻辑只改UI
比如有一些复杂的计算逻辑,我们可以通过C++来实现,这样效率来说也会更高
QML调用C++方法主要有两种方式
注册法
暴露法
本文主要详解Q_INVOKABLE的关键字,通过两种方法来调用C++ 方法

1.创建一个C++方法类

利用Qt的元对象,通过Q_INVOKABLE或public slots注册到元对象系统中,进而通过函数名称直接进行调用。这里先创建一个QObject的派生类,用于实现Qml中需要调用的方法

//=================================QmlControl.h=================================//
#pragma once
#include <QObject>
class QmlControl : public QObject
{
Q_OBJECT

public:
QmlControl(QObject *parent=nullptr);
~QmlControl();
//方式一
Q_INVOKABLE void AddData(int a,int b);
Q_INVOKABLE QString UpdateBackground();
//方式二(等价)
//public slots:
// void AddData(int a, int b);
// QString UpdateBackground();
};
//=================================QmlControl.cpp=================================//
#include "QmlControl.h"
#include <QDebug>
QmlControl::QmlControl(QObject *parent) : QObject(parent) {}
QmlControl::~QmlControl() {}
void QmlControl::AddData(int a, int b) {
qDebug() << "a=" << a << "b=" << b;
qDebug() << "a+b=" << a + b;
}
QString QmlControl::UpdateBackground() {
return QString("http://image.nbd.com.cn/uploads/articles/images/673466/500352700_banner.jpg");
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2.1 qmlRegisterType注册法

使用qmlRegisterType注册一个可以被Qml识别的类型并调用

/*
template<typename T>
int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const
char *qmlName)
uri:qml中的包名
versionMajor:主版本号
versionMinor:副版本号
qmlName:qml中类型名称
*/
qmlRegisterType<QmlControl>("test.conrtrol", 1, 0, "QmlControl");
QQuickWidget *qml_widget = new QQuickWidget();
qml_widget->setResizeMode(QQuickWidget::SizeRootObjectToView);
qml_widget->setSource(QUrl("test_qml.qml"));
qml_widget->show();
ui.verticalLayout->addWidget(qml_widget);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
关系图


import QtQuick 2.12
import QtQuick.Window 2.14
import QtQuick.Controls 2.14
import QtQuick.Controls.Styles 1.4
import test.conrtrol 1.0
Rectangle {
color: "gray"
radius:10
QmlControl {
id: qmlctrl
}
Image {
id:background_image
anchors.fill: parent
fillMode: Image.PreserveAspectCrop
source: "http://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg"
antialiasing: true
}
Button {
text: "Left"
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.leftMargin:50
background: Rectangle {
color:"#0b81ff"
implicitWidth: 100;
implicitHeight: 50;
radius: 6;
}
//信号槽连接
onClicked: {
qmlctrl.AddData(99,88);
console.log("我被点击了"+text)
}
}
Button {
text: "Right"
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.rightMargin:50
background: Rectangle {
color:"#0b81ff"
implicitWidth: 100;
implicitHeight: 50;
radius: 6;
}
//信号槽连接
onClicked: {
background_image.source=qmlctrl.UpdateBackground();
console.log("我被点击了"+text)
}
}
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
2.2 setContextProperty暴露法

通过 setContextProperty暴露给Qml,这里都是以QQuickWidget举例(Qml与QWidget混合开发)

//注册方式二(写法1)
//QQmlApplicationEngine *engine = new QQmlApplicationEngine();
//engine->rootContext()->setContextProperty("qml_ctrl", &qml_control);
//QQuickWidget *qml_widget = new QQuickWidget(engine,nullptr);
//注册方式二(写法2)
QQuickWidget *qml_widget = new QQuickWidget();
qml_widget->rootContext()->setContextProperty("qml_ctrl", &qml_control);

qml_widget->setResizeMode(QQuickWidget::SizeRootObjectToView);
qml_widget->setSource(QUrl("test_qml.qml"));
qml_widget->show();
ui.verticalLayout->addWidget(qml_widget);
1
2
3
4
5
6
7
8
9
10
11
12
这种暴露的方式,无需要引入包名,并且在外部定义了C++类,调用C++方法为

> 注册名.function()
//qml_ctrl.UpdateBackground();
//qml_ctrl.AddData(99,88);
1
2
3
关系图


暴露法和注册法区别

setContextProperty 的暴露法C++类实列化一次,可能同时被多个qml共享,C++类需要我们来维护生命周期,要自己手动释放。在QQuickWidget控件中,如果不同的QQuickWidget共享了同一个QQmlApplicationEngine,则这个QQmlApplicationEngine下暴露的C++类是共享的。
qmlRegisterType 则是每个文件qml中创建由C++导出的类型,实例后使用,全局不唯一。
————————————————
版权声明:本文为CSDN博主「BUG_C++」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u013052326/article/details/125585514

 

标签:widget,QmlControl,int,QQuickWidget,C++,qml,初探,Qml
From: https://www.cnblogs.com/im18620660608/p/17091489.html

相关文章

  • QML(14)——QML与C++交互方式总结1/3(qml调用C++的public函数)
    一、效果qml文件中,可以调用C++类的公共函数   二、步骤1、C++类文件创建C++文件时,一定要勾选下面3项 MyQmlClass.h #ifndefMYQMLCLASS_H#defineMYQMLCL......
  • C++校园导游系统[2023-02-04]
    C++校园导游系统[2023-02-04]校园导游问题描述:用无向网表示校园景点平面图,图中顶点表示主要景点,存放景点的编号、名称、简介等信息,图中的边表示景点间的道路,存放路径......
  • C++ 引用:他是坤坤也是鸡哥
    一、前言作为一名ikun,我最喜欢的明星就是坤坤,但是坤坤又不只叫坤坤,因为他的成名之作《鸡你太美》,ikun们就经常亲切的叫他鸡哥。这个过程中,鸡哥就是我们ikun给偶像坤坤......
  • c++ 一键提取pdf文件图片工具
    日常工作的时候,有时候需要将一个pdf文件中的图片全部提取出来使用,那么这时候就需要一个简单的方法来做这个事情,而不是一个一个图片截图做操作。效果如下:工具下载地址:​​pdf......
  • C/C++BUG: [Error] invalid array assignment
    在写字符串赋值给结构体成员的时候出现的报错报错的行,代码表示改变数据BookName,是将数据存储到结构体中,但是这样赋值会报错。报错这是结构体的组成,result是指向链表其......
  • c++函数
    一,函数基础1.函数一般用一个名字表示,即函数名。返回类型,函数名,参数列表,和函数体构成了函数定义。函数定义的语法形式类型说明符 函数名(含类型说明的形式参数表){ 函数体}......
  • c++中类模板遇到的 不知道怎么解决
    提问:   指定name类型为string填写string的字符串报错啥原因不清楚但报错现实填入的是一个char数组也不知道啥原因解答: 参考代码:template<typenameNameT......
  • C++面试八股文快问快答のSTL篇
    文章目录​​STL篇​​​​vector的底层原理(此题本人踩坑,需重视)​​​​vector中的reserve和resize的区别​​​​vector中的size和capacity的区别​​​​vector中erase方......
  • 【c/c++】isdigit()函数
    isdigit函数isdigit是计算机C(C++)语言中的一个函数,主要用于检查其参数是否为十进制数字字符。函数定义:​​intisdigit(intc)​​​函数说明:​​检查参数是否为十进制......
  • C++
    t[i]=s[j];i++;j++;注意与自增运算符的前缀形式区别,如果是:t[++i]=s[++j];则等价于:i++;j++;t[i]=s[j];贴一段课本上的介绍:1.++i:表示在引用变量i之......