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

QML学习笔记(四十五)QML与C++交互:信号槽的双向实现

前言

在qml内部,我们已经学习过用Connections来连接不同组件间的信号和槽函数(处理器),但其实我们只要在qml中暴露过c++类的上下文属性,我们就可以以相同的方法绑定该c++类的槽函数,以此来实现c++端和qml端的信号槽绑定。

一、c++端的信号

我们新建一个c++类叫CppSignalSender:
.h:

#ifndef CPPSIGNALSENDER_H
#define CPPSIGNALSENDER_H#include <QObject>
#include <QTimer>class CppSignalSender : public QObject
{Q_OBJECT
public:explicit CppSignalSender(QObject *parent = nullptr);signals:void callQml(QString parameter);void cppTimer(QString value);public slots:void cppSlot();private:QTimer m_timer;int m_value;};#endif // CPPSIGNALSENDER_H

.cpp:

#include "cppsignalsender.h"CppSignalSender::CppSignalSender(QObject *parent): QObject(parent),m_timer(new QTimer(this)),m_value(0)
{connect(&m_timer, &QTimer::timeout, this, [=](){++m_value;emit cppTimer(QString::number(m_value));});m_timer.start(1000);
}void CppSignalSender::cppSlot()
{emit callQml("Information from C++");
}

这里实现了两个信号,和一个定时器。我希望实现两个小功能:
1.qml端点击按钮后,通过上下文属性直接调用cppSlot槽函数,然后再发出callQml信号,回到qml端的Connections。
2.c++端通过定时器每秒累加value,并且将当前数字通过cppTimer信号发送到qm端。这里直接在构造函数里lamada表达式写了。

最后,我们再main中暴露该c++对象的上下文属性:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "cppsignalsender.h"int main(int argc, char *argv[])
{QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);QGuiApplication app(argc, argv);QQmlApplicationEngine engine;CppSignalSender sender;engine.rootContext()->setContextProperty("CppSignalSender", &sender);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();
}

二、QML绑定信号

import QtQuick 2.14
import QtQuick.Window 2.14
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12Window {visible: truewidth: 640height: 480title: qsTr("QmlCppSignalSend")Connections{target: CppSignalSenderonCallQml: function(parameter){console.log("This is QML: callQml signal cought:")mText.text = parameter}onCppTimer: function(value){mRectText.text = value}}Column{Rectangle{width: 200height: 200color: "red"radius: 10Text {id: mRectTexttext: "0"anchors.centerIn: parentcolor: "white"font.pointSize: 30}}Button{text: "Call C++ Method"onClicked: {CppSignalSender.cppSlot()}}Text {id: mTexttext: qsTr("Default")}}
}

代码比较简单,Connections中直接对CppSignalSender这个target的信号进行了槽函数重载,然后就可以改变按钮的文本了。
效果:
在这里插入图片描述

三、反过来QML发信号给C++

虽然我们知道qml端可以直接通过c++暴露的上下文属性名,直接调用它的槽函数。但实际上我们也可以将qml和C++对象的信号槽绑定起来,实现端在C++业务代码中。
我在qml中添加一个按钮:

Button{text: "send"objectName: "qmlSender"property int value: 0signal sendValue(int value)   // 自定义信号onClicked: {value++sendValue(value)}
}

这里每点击一下按钮,就会自动递增value,并将它通过信号发送出去。这里它并不知道具体会有谁来接收这个东西,我们在main也就是c++端看实现:

// engine 加载完 QML 后
QObject *qmlObj = engine.rootObjects().first()->findChild<QObject*>("qmlSender");
if (qmlObj){// 普通槽函数QObject::connect(qmlObj, SIGNAL(sendValue(int)),&sender,   SLOT(onQmlSendData(int)));}

我们查找到qmlObj后,就像普通的c++信号槽一样,直接connect连接信号和刚才的c++类CppSignalSender。
最后,我在CppSignalSender中实现这个槽函数:

void CppSignalSender::onQmlSendData(int value)
{qDebug()<<"c++ recv value: "<<value;
}

运行看打印:
在这里插入图片描述

四、总结

信号槽是qt中的最大特色机制,c++端和qml端 能够顺利通过信号槽来连接,也是其设计的侧重所在。在这种需要更改界面组件中的信息时,通过信号槽来实现显然是更优的选择。
而信号槽的使用,也可以降低双方之间的耦合性,只需要获取到对方的obj(属性或指针),然后只管发送信号,具体实现就不需要管了。

http://www.dtcms.com/a/512051.html

相关文章:

  • 【JavaWeb|第二篇】SpringBoot篇
  • 手机做网站过程广州网站开发设计
  • 惠州百优做网站小程序熊掌号网站改版提案
  • 设计基于LLM的MCP工具:智能工具选择与DAG执行流程
  • 第三方软件课题结题验收测试机构【使用JMeter的Web应用负载测试】
  • 网站建设时间进度表模板wordpress批量修改链接
  • 如何做视频网站赚钱孙俪做的网站广告
  • 华为od-22届考研-测试面经
  • 深度学习卷积层
  • 网页设计模板图片素材下载重庆公司seo
  • 网站先做移动站在做pc站可行吗工程服务建设网站
  • C++第十三篇:继承
  • GD32F407VE天空星开发板SPI配置详解
  • 公司网站建设优帮云企业网站建设需注意什么
  • 垂直原理:宇宙的沉默法则与万物运动的终极源头
  • 如何在没有 iCloud 的情况下备份 iPhone
  • 江苏专业网站建设ps软件手机版
  • 番禺制作网站平台女孩学电子商务专业好就业吗
  • 自动点焊机——为电动自行车打造稳定动力
  • 栈与队列:数据结构中的双雄对决
  • Jenkins 安装,自动化全方位详解文档
  • 第八节_PySide6基本窗口控件_按钮类控件(QAbstractButton)
  • iBizModel 工作流(PSWORKFLOW)模型体系详解
  • 装修公司网站源码网站怎样做免费优化有效果
  • 20.1 ChatPPT v3.0颠覆发布:多模态图像识别+AI生成,办公效率提升500%的核心拆解
  • 【PyTorch】单目标检测部署
  • 3D超点(3D Superpoint)概念解释与代码实现
  • TPAMI 2025 | 从分离到融合:新一代3D场景技术实现双重能力提升!
  • malloc/free 内存问题
  • 国企集团门户网站建设方案有什么做数学题的网站