当前位置: 首页 > news >正文

【Qt- C++ Qml 交互】

Qt编程指南 VX:hao541022348

  • ■ 将C++对象注册到 QML中,在QML使用C++对象
    • ■ C++对象注册到元对象系统
    • ■ Q_INVOKABLE 宏定义是将C++ 的 函数(方法)声明为元对象系统可调用的函数
    • ■ 演示步骤
  • ■ 将 C++类注册到 QML,并在QML声明一个对象并进行访问
    • ■ qmlRegisterType函数(将c++类注册到qml中)
  • ■ QML暴露对象给 C++ 进行交互
  • ■ C++ 创建 QML 对象并进行交互
  • ■ C++ 对象与 QML 通过信号槽进行交互

■ 将C++对象注册到 QML中,在QML使用C++对象

在 C++ 里定义了一个对象,然后将这个对象注册到 QML 里面。在 QML 里面访问的就是 C++ 定义的对象。

■ C++对象注册到元对象系统

QQmlApplicationEngine::rootContext()->setContextProperty()

■ Q_INVOKABLE 宏定义是将C++ 的 函数(方法)声明为元对象系统可调用的函数

Q_INVOKABLE
Q_INVOKABLE 是个宏定义,这个宏将 函数 声明为元对象系统可调用的函数

  • Q_INVOKABLE 是个宏定义
  • 这个宏定义 针对的是 函数, 不是变量
  • 经过Q_INVOKABLE 声明过得函数 可以被元对象系统调用
  • QtQuick 也在元对象系统内,所以在 QML 中也可以访问这个被声明了的函数

■ 演示步骤

  1. 新建qml工程,里面只有一个main.cpp 与一个默认的 main.qml
  2. 创建一个C++ 的类 MyQmlClass 来与 QML 进行交互(重点关注 函数 Q_INVOKABLE宏
  3. 将 C++ 的对象,注册到 QML中去 QQmlApplicationEngine::rootContext()->setContextProperty()
  4. 做完了这两步,我们就做了 C++ 的工作,在 QML 中 就可以 直接拿到对象 myQmlImp 来调用使用 Q_INVOKABLE 定义的方法了。
  5. 改造 QML (定义一个“获取”的 Button 与 显示获取值得 Label, 点击 Button 就会获取 C++ 中的 m_value 值, 在 Lable 上进行展示。)

MyQmlClass.h

#ifndef MYQMLCLASS_H
#define MYQMLCLASS_H#include <QObject> 
class MyQmlClass : public QObject
{Q_OBJECT
public:explicit MyQmlClass(QObject *parent = nullptr);Q_INVOKABLE void setValue(int value);    //这个宏将 函数 声明为元对象系统可调用的函数Q_INVOKABLE int getValue();   //这个宏将 函数 声明为元对象系统可调用的函数signals:private:int m_Value;
};#endif // MYQMLCLASS_H

MyQmlClass.cpp

#include "MyQmlClass.h"MyQmlClass::MyQmlClass(QObject *parent) : QObject(parent)
{}void MyQmlClass::setValue(int value)
{m_Value = value;
}int MyQmlClass::getValue()
{return m_Value;
}

打开 main.cpp ,通过 QML 引擎 QQmlApplicationEngine 进行注册。

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>#include "MyQmlClass.h"int main(int argc, char *argv[])
{QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); QQmlApplicationEngine engine;/////声明 对象  首先定义了一个C++ 的对象 myQmlImp ,MyQmlClass myQmlImp; //将对象进行注册到QML中//key :自定义字符串,为了好记,我们这里叫做对象的名字 "myQmlImp"//value : 对象引用,对象指针,这里就是&myQmlImpengine.rootContext()->setContextProperty("myQmlImp", &myQmlImp);/// 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();
}

main.qml我们的思路很简单,就是 QML 中来调用上面 C++ 暴露出来的读写函数。所以我们在QML 中定义一个 “获取” Button ,点击它我们就来调用C++中的 getValue() 函数,然后我们需要一个Label 将获取的 C++ 的值进行展示

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.3Window {visible: truewidth: 640height: 480title: qsTr("Hello World")Label{                         //Label用于显示获取C++的值id: label                  //显示控件,唯一标识ID:labeltext: ""                   //初始化内容清空anchors.bottom: getBtn.top //显示控件的下方放到btn的上方anchors.left: getBtn.left  //显示控件的左方与btn的左侧对齐}Button{                       //Button 用于获取值id: getBtn                 //按钮控件,唯一标识ID:getBtntext: "获取"                //按钮显示文字width: 120                 //按钮宽度height: 40                 //按钮高度anchors.centerIn: parent   //按钮放到窗口中心onClicked: {               //点击按钮事件;label.text = myQmlImp.getValue()}}
}

在这里插入图片描述
到这里,我们就在 QML 中获取了 C++ 代码中的值。可能到这里还有老师感觉不太真实,那么我们就继续进行验证,我们的思路是这样的:

  1. 我们增加一个 TextFiled 用于输入我们想给 。
  2. 再增加一个 “设置” 按钮,将 1中输入的值,给C++ 中的 m_Value 设值。
  3. 然后我们再点击刚才的 “获取” 按钮,将 C++ 中的 m_Value 值读取并显示出来。
    这时候我们需要对原来的QML进行改造,新增加一个输入框TextField ,进行数值输入; 还需要新增加一个“设置” 按钮,点击按钮将值赋给 C++ 中的 m_Value

main.qml

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.3Window {visible: truewidth: 640height: 480title: qsTr("Hello World") Label{                         //Label用于显示获取C++的值id: label                  //显示控件,唯一标识ID:labeltext: ""                   //初始化内容清空anchors.bottom: getBtn.top //显示控件的下方放到btn的上方anchors.left: getBtn.left  //显示控件的左方与btn的左侧对齐}Button{                       //Button 用于获取值id: getBtn                 //按钮控件,唯一标识ID:getBtntext: "获取"                //按钮显示文字width: 120                 //按钮宽度height: 40                 //按钮高度anchors.centerIn: parent   //按钮放到窗口中心onClicked: {               //点击按钮事件;label.text = myQmlImp.getValue()}}TextField{                      //文字输入控件id: textField               //唯一IDwidth: getBtn.width         //也可以直接设置成120height: getBtn.height       //也可以直接设置成40anchors.top: getBtn.bottom  //放到“获取”按钮下方10个像素anchors.topMargin: 10anchors.left: getBtn.left   //与“获取”按钮左对齐}Button{id: setBtntext: "设置"width: textField.width      //可以设置成getBtn.width或者120height: textField.height    //可以设置成getBtn.height或者40anchors.top: textField.bottomanchors.left: textField.leftonClicked: {var value = textField.textmyQmlImp.setValue(value)} }  
}

在这里插入图片描述

■ 将 C++类注册到 QML,并在QML声明一个对象并进行访问

■ qmlRegisterType函数(将c++类注册到qml中)

qmlRegisterType 就是一个函数模板。将 C++ 的类型注册到 QML 系统中,并且带有版本号,方便版本管理。 我们就把main.cpp 中的函数改造一下:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext> 
#include "MyQmlClass.h"int main(int argc, char *argv[])
{QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); QQmlApplicationEngine engine; 
//    方式一:注册定义好的对象到 QML
//    MyQmlClass myQmlImp;
//    engine.rootContext()->setContextProperty("myQmlImp", &myQmlImp);//    方式二:注册类到 QML 对象qmlRegisterType<MyQmlClass>("com.company.myqmlclass", 1, 0, "MyQmlClass");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();
}

其中:qmlRegisterType 模板函数中的 “com.company.myqmlclass” 为自定义的控件名称类似于C++中的库名称。我们在 QML 中需要 import 这个控件名, “MyQmlClass” 为 C++ 注册的类名, 1和0 为自定义版本号,方便版本管理。
在这里插入图片描述

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.3
import com.company.myqmlclass 1.0Window {visible: truewidth: 640height: 480title: qsTr("Hello World")MyQmlClass{id: myQmlImp}Label{                         //Label用于显示获取C++的值id: label                  //显示控件,唯一标识ID:labeltext: ""                   //初始化内容清空anchors.bottom: getBtn.top //显示控件的下方放到btn的上方anchors.left: getBtn.left  //显示控件的左方与btn的左侧对齐}Button{                       //Button 用于获取值id: getBtn                 //按钮控件,唯一标识ID:getBtntext: "获取"                //按钮显示文字width: 120                 //按钮宽度height: 40                 //按钮高度anchors.centerIn: parent   //按钮放到窗口中心onClicked: {               //点击按钮事件;label.text = myQmlImp.getValue()}}TextField{                      //文字输入控件id: textField               //唯一IDwidth: getBtn.width         //也可以直接设置成120height: getBtn.height       //也可以直接设置成40anchors.top: getBtn.bottom  //放到“获取”按钮下方10个像素anchors.topMargin: 10anchors.left: getBtn.left   //与“获取”按钮左对齐}Button{id: setBtntext: "设置"width: textField.width      //可以设置成getBtn.width或者120height: textField.height    //可以设置成getBtn.height或者40anchors.top: textField.bottomanchors.left: textField.leftonClicked: {var value = textField.textmyQmlImp.setValue(value)}}
}

■ QML暴露对象给 C++ 进行交互

■ C++ 创建 QML 对象并进行交互

■ C++ 对象与 QML 通过信号槽进行交互

相关文章:

【Qt- C++ Qml 交互】

Qt编程指南 VX&#xff1a;hao541022348 ■ 将C对象注册到 QML中&#xff0c;在QML使用C对象■ C对象注册到元对象系统■ Q_INVOKABLE 宏定义是将C 的 函数&#xff08;方法&#xff09;声明为元对象系统可调用的函数■ 演示步骤 ■ 将 C类注册到 QML&#xff0c;并在QML声明一…...

ubuntu 20.04 自由切换 python 的版本

问题描述 当前 ubuntu 20.04 默认安装了多个 python 的版本&#xff0c;执行 python 时&#xff0c;默认版本是 Python 2.7.18 zhangszzhangsz:~$ python Python 2.7.18 (default, Jul 1 2022, 12:27:04) [GCC 9.4.0] on linux2 Type "help", "copyright&quo…...

程序性能优化全能手册

本文聊一个程序员都会关注的问题&#xff1a;性能。 当大家谈到“性能”时&#xff0c;你首先想到的会是什么&#xff1f; 是每次请求需要多长时间才能返回&#xff1f; 是每秒钟能够处理多少次请求&#xff1f; 还是程序的CPU和内存使用率高不高&#xff1f; 这些问题基本上…...

LiveSIPB流媒体国网B接口功能-国网B接口服务安装使用说明

LiveSIPB 国网B接口服务安装使用说明 1、服务说明1.1、安装包说明1.2、国网B接口信令服务1.3、国网B接口流媒体服务1.4、配置信令服务(LiveCMS)1.5、配置流媒体服务(LiveSMS) 2、服务运行2.1、Windows2.2、Linux 3、配置设备接入3.1、海康STATE_GRID接入示例 4、平台使用4.1、管…...

利用小红书笔记详情API:为内容运营提供强大的支持

利用小红书笔记详情API&#xff0c;内容运营者可以获得对小红书平台上的笔记内容的深入洞察&#xff0c;从而为其运营工作提供强大的支持。以下是该API如何支持内容运营的几个关键方面&#xff1a; 获取笔记内容与数据&#xff1a; API允许内容运营者直接获取小红书平台上的笔记…...

地理空间分析1——入门Python地理空间分析

写在开头 地理空间分析是一门涉及地球表面数据处理和解释的科学&#xff0c;通过对地理现象的研究&#xff0c;我们可以更深入地了解地球各个角落的关系。Python作为一种功能强大的编程语言&#xff0c;在地理空间分析领域展现了强大的潜力。本文将带您深入了解入门级别的Pyth…...

哈尔滨爆火的背后有什么值得我们学习的,2024普通人如何创业/2024风口行业

这个冬天&#xff0c;“南方小土豆”带火东北冰雪游。“冰城”黑龙江哈尔滨的文旅市场异常火爆&#xff0c;元旦假期3天&#xff0c;哈尔滨市累计接待游客304.79万人次&#xff0c;实现旅游总收入59.14亿元。旅游总收入达到历史峰值。哈尔滨旅游怎么就爆火了&#xff1f;背后究…...

element中Tree 树形控件实现多选、展开折叠、全选全不选、父子联动、默认展开、默认选中、默认禁用、自定义节点内容、可拖拽节点、手风琴模式

目录 1.代码实现2. 效果图3. 使用到的部分属性说明4. 更多属性配置查看element官网 1.代码实现 <template><div class"TreePage"><el-checkboxv-model"menuExpand"change"handleCheckedTreeExpand($event, menu)">展开/折叠&l…...

数据结构OJ实验15-插入排序与交换排序

A. DS内排—直插排序 题目描述 给定一组数据&#xff0c;使用直插排序完成数据的升序排序。 --程序要求-- 若使用C只能include一个头文件iostream&#xff1b;若使用C语言只能include一个头文件stdio 程序中若include多过一个头文件&#xff0c;不看代码&#xff0c;作0分…...

鹿目标检测数据集VOC格式500张

鹿&#xff0c;一种优雅而神秘的哺乳动物&#xff0c;以其优美的外形和独特的生态习性而备受人们的喜爱。 鹿的体型通常中等&#xff0c;四肢细长&#xff0c;身体线条流畅。它们的头部较小&#xff0c;耳朵大而直立&#xff0c;眼睛明亮有神。鹿的毛色因品种而异&#xff0c;…...

静态网页设计——电影推荐网(HTML+CSS+JavaScript)

前言 声明&#xff1a;该文章只是做技术分享&#xff0c;若侵权请联系我删除。&#xff01;&#xff01; 感谢大佬的视频&#xff1a; https://www.bilibili.com/video/BV1NK411x7oK/?vd_source5f425e0074a7f92921f53ab87712357b 使用技术&#xff1a;HTMLCSSJS&#xff08;…...

ARM CCA机密计算架构软件栈简介

本博客描述了Arm机密计算架构(Arm CCA)的固件和软件组件。 在这篇博客中,您将学到如何: 列出组成Arm CCA软件栈的组件集了解Arm CCA引入新软件组件的原因了解监视器和领域管理监视器(RMM)的角色了解如何创建和管理领域1.1 开始之前 我们假设您熟悉AArch64异常模型、AAr…...

C#编程-使用集合

使用集合 您学习了如何使用数组来有效地存储和操作相似类型额数据。但是,以下限制于数组的使用相关联: 您必须在声明时定义数组的大小。您必须编写代码以对数组执行标准操作,如排序。让我们思考一个示例。假设您想要存储在组织工作的五个雇员的姓名。您可以使用以下语句来声…...

linux 设备模型之设备

在最低层, Linux 系统中的每个设备由一个 struct device 代表: struct device { struct device *parent; struct kobject kobj; char bus_id[BUS_ID_SIZE]; struct bus_type *bus; struct device_driver *driver; void *driver_data; void (*release)(struct device *dev); /* …...

电源滤波可采用 RC、LC、π 型滤波。电源滤波建议优选磁珠,然后才是电感。同时电阻、电感和磁珠必须考虑其电阻产生的压降。

电源滤波是为了减少电源中的噪声和干扰,确保电子设备正常工作。RC、LC、π 型滤波是常用的电源滤波器结构,其选择主要取决于需要滤波的频率范围和所需的滤波效果。 RC滤波器是由电阻和电容组成,适用于高频噪声的滤波。当电流通过电容时,电容会阻止高频噪声信号的通过,起到…...

STM32通用定时器-输入捕获-脉冲计数

一、知识点 编码器   两相编码器&#xff08;正交编码器&#xff09;&#xff1a;两相编码器由 A 相和 B 相组成&#xff0c;相位差为 90 度。当旋转方向为顺时针时&#xff0c;A 相先变化&#xff0c;然后 B 相变化&#xff1b;当旋转方向为逆时针时&#xff0c;B 相先变化…...

Flutter GetX 之 路由管理

路由管理是插件GetX常用功能之一&#xff0c;为什么说之一呢&#xff1f;因为GetX的功能远不止路由管理这么简单。 GetX的重要功能如下&#xff1a; 1、路由管理2、状态管理3、国际化4、主题5、GetUtil工具6、dialog 弹框7、snackbar 其实上面功能介绍的还是不够详细&#xff…...

基于单片机的农田灌溉系统(论文+源码)

1.系统设计 本系统主要实现如下目标&#xff1a; 1&#xff0e;可以实时监测土壤湿度&#xff1b; 2&#xff0e;土壤湿度太低时&#xff0c;进行浇水操作&#xff1b; 3&#xff0e;可以按键设置湿度的触发阈值&#xff1b; 4. 可以实现远程操控 5&#xff0e;可以实现手…...

分布式缓存 -- 基础

负载均衡 Ribbon 服务间通信的负载均衡工具&#xff0c;提供完善的超时重试机制 客户端的负载均衡器&#xff1a;在客户端将各个服务的信息拿到&#xff0c;在客户端本地做到请求的均衡分配 Ribbon 提供 LoadBalanced 注解&#xff0c;外搭配RestTemplate来做客户端的负载均衡…...

云计算复习笔记--期末

1、云计算的定义和本质&#xff1a; 云计算是一种按使用量付费的模式。云计算是分布式计算的一种。通过计算机网络&#xff08;多指因特网&#xff09;形成的计算能力极强的系统&#xff0c;可存储、集合相关资源并可按需配置&#xff0c;向用户提供个性化服务。 2、云计算服…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...