C++与QML 信号与槽交互

news2024/12/28 3:20:08

一、全局属性

在main.cpp中通过 QQmlApplicationEngine engine 获得全局对象

QQmlApplicationEngine engine;    
//全局对象  上下文对象    
QQmlContext* context = engine.rootContext();      
 //获取屏幕的大小     
Screen *screen= QGuiApplication::primaryScreen();     
QRect rect=   screen->virtualGeometry(); //整个屏幕的大小     
//注册的上下文对象 它是作用于全局 有重命名的风险     
context->setContextProperty("SCREEN_WIDTH",rect.width()/2); //设置全局属性 所有QMl文件都能访问得到的

在qml中使用  SCREEN_WIDTH  全局属性

 width: SCREEN_WIDTH    //screen.desktopAvailableWidth 获取整个屏幕的宽度

二,创建自定义对象,在QMl中使用

1.创建一个MyObject类

 2.在myobject.h中定义一些属性,以便在qml中可以使用 并为每个属性添加读写的方法和相应的信号

class MyObject : public QObject
{    Q_OBJECT
      public:   
       explicit MyObject(QObject *parent = nullptr);    
      int iValue() const;
   void setIValue(int iValue);
   QString sString() const;    
  void setSString(const QString &sString);    
//定义一个函数 加Q_INVOKABLE 就可以让qml访问    
Q_INVOKABLE void  func();

private:    
//生成get 和set 方法   
 int m_iValue;   
 QString m_sString;  
 
//宏    
//第一种方式    
//声明一个名称 int iValue  想是QMl 中width    
//READ iValue --->通过那个函数读的    
// WRITE setIValue---》通过那个函数写的    
//NOTIFY iValueChanged 当前这个值修改会发出iValueChanged信号   
/* Q_PROPERTY(int iValue READ iValue WRITE setIValue NOTIFY iValueChanged)    Q_PROPERTY(QString sString READ sString WRITE setSString NOTIFY sStringChanged)*/   //第二种方式   
 Q_PROPERTY(int iValue MEMBER m_iValue NOTIFY iValueChanged)    
Q_PROPERTY(QString sString MEMBER m_sString NOTIFY sStringChanged)

public slots:    
//槽函数    
void ccpSlot(int i,QString str); 
signals:    
void iValueChanged();    
void sStringChanged();    
//定义一个信号,在qml中绑定槽函数    
void cppSig(QVariant i,QVariant s);
};

2.在myobject.cpp中实现

#include "myobject.h"

MyObject::MyObject(QObject *parent) : QObject(parent)
{

}

MyObject *MyObject::getInstance()
{
    static MyObject * obj = new MyObject();
    return obj;
}

int MyObject::iValue() const
{
    return m_iValue;
}

void MyObject::setIValue(int iValue)
{
    if(m_iValue == iValue)
        return;

    m_iValue = iValue;
    //发出信号
    emit iValueChanged();
}

QString MyObject::sString() const
{
    return m_sString;
}

void MyObject::setSString(const QString &sString)
{
    if(m_sString == sString)
        return;
    m_sString = sString;
    emit sStringChanged();
}

void MyObject::func()
{
    emit cppSig(101,"王五"); //发送信号
    qDebug()<<__FUNCTION__;//当前函数名称

}

void MyObject::ccpSlot(int i, QString str)
{
     qDebug()<<__FUNCTION__<<"  "<<i<<" "<<str;
}

3.在main.cpp中访问 定义这个复杂的类型

有两种方式

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QScreen>
#include <myobject.h>
#include <QObject>
int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    //
    //全局对象  上下文对象
    QQmlContext* context = engine.rootContext();

    //获取屏幕的大小
     QScreen *screen= QGuiApplication::primaryScreen();
     QRect rect=   screen->virtualGeometry(); //整个屏幕的大小
     //注册的上下文对象 它是作用于全局 有重命名的风险
     context->setContextProperty("SCREEN_WIDTH",rect.width()/2); //设置全局属性 所有QMl文件都能访问得到的
   
 //qml中就可以访问这个对象myObjectOO
     //但是qml 并不能认识这个这个复杂的类型

     //方式一
     //context->setContextProperty("myObjectOO",MyObject::getInstance());//一般不用这个方法

     //方式二
     //四个参数
     //第一个参数是qml中导入的名称 import HelloMyObj 1.0
     //第二个第三个参数分别是主次版本号;第四个指的是QML中类的名字。
     //qmlRegisterType<MyObject>("HelloMyObj",1,0,"MyObject");
     //我们一定要通过创建对象来定义一个我们自定义的object

     //创建一个全局的单例的模式
     qmlRegisterSingletonInstance("HelloMyObj",1,0,"MyObject",MyObject::getInstance());


///
    //地址
    const QUrl url(QStringLiteral("qrc:/CPPSlotSignal.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);

/
    //C++端绑定qml中发出的信号
    //engine 加载完成后 load以后
    auto list = engine.rootObjects(); //返回CPPSlotSignal.qml 中所有的对象
    //auto objectName = list.first()->objectName();
   // auto btnName = list.first()->findChild<QObject *>("btnClick");
   // qDebug()<<btnName;
    auto window = list.first();
    //绑定
    QObject::connect(window,SIGNAL(qmlSig(int,QString)),
                     MyObject::getInstance(),SLOT(ccpSlot(int,QString)));
    //绑定
    QObject::connect(MyObject::getInstance(),SIGNAL(cppSig(QVariant,QVariant)),
                    window,SLOT(qmlSlot(QVariant,QVariant)));

///
    return app.exec();
}

4.在qml中访问

需要导入对象名和主次版本号 ,才能正式使用

import HelloMyObj 1.0

import QtQuick 2.14
import QtQuick.Window 2.14
import QtQuick.Controls 2.12

import HelloMyObj 1.0

Window {
    id: window

    property int value: myobj.ivalue
    visible: true
    width: 640
    height: 480
    title: qsTr("hello")


  MyObject{
       id: myobj

       iValue:20

      sString:"hello"
  }

onValueChanged:

{

  console.log(value)

}

Button{

onClicked: {

   myobj.iValue = 20

}


}

三、QML端发送信号,绑定c++端的函数

1.在qml写好信号,并发出

Window {    
id: window   
 objectName: "window"   
 visible: true   
 width: 640    
height: 480    
title: qsTr("QML端发送信号,绑定c++端的函数")
//信号   
 signal qmlSig(int i,string s)   
 Button {        
 objectName: "btnClick"        
onClicked: {           
  //发送信号          
 qmlSig(22,"hello")           
       
}    
}

2.在类中定义槽函数

public slots:    
//槽函数    
void ccpSlot(int i,QString str);

实现

void MyObject::ccpSlot(int i, QString str)
{    
 qDebug()<<__FUNCTION__<<"  "<<i<<" "<<str;
}

3.绑定信号与槽函数

3.1在main.cpp绑定----C++端绑定qml中发出的信号

//engine 加载完成后 load以后    
auto list = engine.rootObjects(); //返回CPPSlotSignal.qml 中所有的对象    
//auto objectName = list.first()->objectName();   
// auto btnName = list.first()->findChild<QObject *>("btnClick");   
// qDebug()<<btnName;    
auto window = list.first();    
//绑定    
QObject::connect(window,SIGNAL(qmlSig(int,QString)),                                    MyObject::getInstance(),SLOT(ccpSlot(int,QString)));

3.2在qml端绑定C++类的槽函数  两种方式

 MyObject{
 id: myobj
 }    
//连接C++中槽函数    
//1.   
 /*Connections{        
target: window //发出者        
function onQmlSig(i,str){           
 myobj.ccpSlot(i,str)        
}    
} 
 */   
 //2.在组件完成时与连接   
/* Component.onCompleted: {       
 qmlSig.connect(myobj.ccpSlot)    
}    */

四、c++端发出信号,qml端绑定槽函数

1.myobject.h的定义信号

//定义一个信号,在qml中绑定槽函数   
 void cppSig(QVariant i,QVariant s);

2.在qml中定义槽函数

    function qmlSlot(i,s){  // 参数类型 对应CPP端 都是QVariant                   console.log("qml",i,s)    
}

3.绑定

3.1c++端绑定

auto list = engine.rootObjects();
auto window = list.first(); QObject::connect(MyObject::getInstance(),SIGNAL(cppSig(QVariant,QVariant)),                      window,SLOT(qmlSlot(QVariant,QVariant)));

3.2qml端绑定

Connections{            
target: MyObject //发出者            
function onCppSig(i,str){               
 qmlSlot(i,str)       
     }

4.可以不用在qml实现MyObject 对象,只需要在main中创建一个全局的单例的模式

 qmlRegisterSingletonInstance("HelloMyObj",1,0,"MyObject",MyObject::getInstance());

五、C++端直接调用QML函数

1.qml中写函数


    function qmlFunc(i,s){
        return " are you ok?"
    }

2.在main.cpp中调用

auto list = engine.rootObjects(); //返回CPPSlotSignal.qml 中所有的对象
auto window = list.first();
//调用QML端的函数    
//第一参数,拥有者  第二参数 函数名称 第三参数 保存到哪  后面就是要传递的参数   
 QVariant resFunc;    
QVariant arg_1 = 123;    
QVariant arg_2 = "I am fine ";    
QMetaObject::invokeMethod(window,"qmlFunc",                              Q_RETURN_ARG(QVariant,resFunc),                                     Q_ARG(QVariant,arg_1),     
Q_ARG(QVariant,arg_2));
qDebug()<<"res = "<<resFunc;

3.在qml中调用c++中的函数

3.1在myobject.h中定义

//定义一个函数 加Q_INVOKABLE 就可以让qml访问    
Q_INVOKABLE void  func();

3.2在qml中使用

 Button {        
objectName: "btnClick"       
 onClicked: {  
 MyObject.func()       
 }    
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/691287.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

jquery基础知识整理

写在前面的话&#xff1a;由于公司做的政府网站&#xff0c;需要考虑到兼容ie。所以我们使用jquery解决方案。在一些展示类的、不是一个多网页的整体应用中。我们仍然可以使用jQuery进行开发。 以下是我看慕课网整理的jQuery知识。慕课网课程链接jQuery课程。 以下是我整理的知…

文档识别开发“零门槛”!合合信息智能文字识别技术助力柳州银行“降本增效”

现阶段&#xff0c;越来越多的金融机构将业务转到线上&#xff0c;推出了“零接触”金融服务以提升业务流程效率。在此过程中&#xff0c;智能文字识别技术对提升复杂版式文档录入效率起到了重要作用。 近期&#xff0c;在元脑生态框架下&#xff0c;合合信息将智能文字识别技…

数学建模算法(基于matlab和python)之 三次样条插值与多项式拟合(2/10)

实验目的及要求&#xff1a; 1、会在Matlab平台上进行样条插值&#xff1b; 2、会在Matlab平台上进行最小二乘拟合。 实验内容&#xff1a; 1、利用spline函数绘制【0&#xff0c;10】内步长为1的插值节点处的的样条曲线。 2、根据下列数据三转角方程法构造三次样条函数…

Linux命令大全(面试必备)

前两节有说Git命令&#xff0c;反馈还不错&#xff0c;看来大家对这些必备的命令还挺感兴趣哈&#xff0c;这节就罗列一些Linux必须掌握的命令。 干货满满哦&#xff0c;直接发车... 一、常用的基本命令 1、关机开机 关机 shutdown-h now 立刻关机shutdown-h 3 3分钟后关机…

Java八股文面试(黑马)

Redis篇 数据库的并发不高&#xff0c;请求到了一定的量就会击垮数据库&#xff0c;导致宕机。 大概率是客户端正好在写入数据&#xff0c;sentinel与当前master出现分区 而 重新选举了一个master Mysql篇

IOS 手机抓包 频繁 访问 gateway.icloud.com.cn:443

在抓包的时候&#xff0c;有时候苹果手机在重启后频繁出现gateway.icloud.com.cn:443请求 这种情况需要在手机上进行设置&#xff0c;适用于IOS16.0以上版本&#xff0c;其他版本不清楚&#xff0c;没有尝试过 进入 设置--点击AppleID &#xff0c;进入个人信息页面---点击iCl…

开发工具-网络测试工具 POSTMAN 的脚本使用

开发工具-网络测试工具 POSTMAN 的脚本使用 postman 脚本应用基础设置变量、获取变量示例环境变量的使用测试 发送请求示例常用的变量、方法responseBody 获取响应体内容pm.response 获取响应信息pm.expect() JSON检查cheerio.load() 类似于 jquery 操作 html 元素 POSTMAN 是网…

做独立站要选择什么样的产品呢?这些要点要注意!

跨境圈都在说独立站能不能成功七分靠选品&#xff0c;三分靠运营&#xff0c;可见选品是决定独立站能不能成功的一大关键因素&#xff0c;只有先选定了产品&#xff0c;才能进行店铺装修、物流设置&#xff0c;以及后续的运营工作。 那么独立站的卖家应该如何去选品呢&#xf…

一文搞懂ASCII、Unicode与UTF-8

目录 一、前置知识二、ASCII三、从ASCII到Unicode四、Unicode五、UTF-8六、总结References 一、前置知识 一个字节有8-bit&#xff1b;一个十六进制数占4-bit&#xff0c;故一个字节可以表示为两个十六进制数&#xff08;通常会加上 0x 前缀&#xff09;&#xff1b;十六进制通…

基于Python+OpenCV的视频字符化(深度学习+机器视觉)含全部工程源码

目录 前言总体设计系统整体结构图系统流程图 运行环境Python 环境OpenCV环境 模块实现1. 视频读取及处理2. 色素块识别与替换3. 视频合成4. 操作系统上的实现 系统测试工程源代码下载其它资料下载 前言 本项目利用 OpenCV 提供的轻量、高效的 C类和 Python 接口&#xff0c;实…

数据平台流量回放最佳实践|精选

1.1 数据平台业务背景 数据平台利用大数据智能分析、数据可视化等技术&#xff0c;对公司内外部经过采集、建设、管理、分析的多源异构数据进行呈现和应用&#xff0c;实现了数据共享、日常报表自动生成、快速和智能分析&#xff0c;深度挖掘数据价值&#xff0c;满足企业各级…

Leetcode48 旋转图像

给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出…

ZYNQ——按键消抖实验

文章目录 原理简介软件仿真板上验证 原理简介 按键作为基本的人机输入接口&#xff0c;在很多电子设计中都是比较常见的&#xff0c;但是由于其机械特性&#xff0c;在按键按下或者松开的时候&#xff0c;按键的输入值是有抖动的。按键的抖动是其固有特性&#xff0c;因此无论…

打死也不要进外包,来看看我在腾讯外包的这2年......

我18年毕业于一个普通二本学校&#xff0c;是一个很不出名的小本科。大学期间专业知识也没有去认真的学习&#xff0c;所以毕业的时候就随便找了一份工作&#xff0c;在一个小公司做功能测试。 记得那时候薪资大概是6k左右&#xff0c;因为是在工厂&#xff0c;工作环境很差&a…

Gitlab 访问令牌更新 替换

引言 访问令牌到期后如何丝滑更换&#xff0c;或则如何更改账户的访问令牌实现权限变动呢&#xff1f;在我们使用访问令牌克隆项目之后&#xff0c;Windows凭据就帮我们记录下了密码。当然密码是不可见的&#xff0c;只能进行删除重新设置&#xff0c;通过凭据管理器进行更改。…

python基于预训练大模型权重实现文本向量化开发构建微博评论数据情感极向识别模型

因为最近的一些项目涉及到了大模型相关的技术开发研究&#xff0c;在我前面的博文中也已经有一些实践记录学习资料分享的文章了&#xff0c;今天是在做模型训练的时候突然想到一个有意思的想法&#xff0c;按照我之前做文本分类的方法&#xff0c;基本主流的技术路线都是先对文…

性能提升571%,32K超长上下文,推理速度提升42%,允许商用,国产开源大模型推出了二代 ChatGLM2-6B...

6月份是火热的夏天&#xff0c;各种火热的 AI 产品也在密集的更新&#xff0c;天越热&#xff0c;大家是干得热火朝天&#xff0c;卷出了新高度。 前有现在大火的 ChatGPT&#xff0c;ChatGPT 更新&#xff1a;大杀器&#xff01;函数调用示范&#xff0c;ChatGPT 3.5/4 双双升…

Java Web JDBC(2)23.6.26

3.6 PreparedStatement PreparedStatement作用&#xff1a; 预编译SQL语句并执行&#xff1a;预防SQL注入问题 3.6.1 代码模拟SQL注入问题 Test public void testLogin() throws Exception {//2. 获取连接&#xff1a;如果连接的是本机mysql并且端口是默认的 3306 可以简化书…

浅谈无线温度监测系统在冶炼厂供配电的应用

安科瑞 华楠 摘要&#xff1a;高压供配电系统运行稳定性与电气元器件连接点温度密切相关&#xff0c;通过与传统测温方法对比&#xff0c;实时在线无线温度监测解决 了密封高压开关柜内部各连接点温度无法检测的难题&#xff0c;满足了供电系统安全稳定运行的要求&#xff0c;降…

redis 主从复制 哨兵 安装部署

学习开始前先了解一下 Redis是一个开源的内存数据结构存储系统&#xff0c;它支持多种数据结构&#xff0c;如字符串、哈希表、列表、集合、有序集合等。Redis最大的特点是数据存储在内存中&#xff0c;因此读写速度非常快&#xff0c;同时也支持数据持久化&#xff0c;可以将数…