QT C++(信号与槽函数,自定义信号和槽函数)

文章目录

  • 1. QT信号与槽函数
  • 2. QT自定义信号和槽函数

1. QT信号与槽函数

QT信号关键要素:

  1. 信号源:那个控件发送的信号
  2. 信号类型:用户进行不同的操作,就可能触发不同的信号。
    eg:点击按钮,移动鼠标等
  3. 信号处理方式:使用槽函数(slot)将信号与对应的信号处理函数关联起来(回调函数)

在QT中使用connect函数关联信号和信号处理函数(槽函数),这个函数是QObject类(基类)的静态成员函数

connect函数原型

 static QMetaObject::Connection connect(const QObject *sender, const char *signal,
                        const QObject *receiver, const char *member, Qt::ConnectionType type= Qt::AutoConnection);
  • sender:当前信号是那个控件发送的(信号源)
  • singal:信号的类型,发送的是那种信号
  • receiver+member:信号如何处理
    • receiver:那个对象负责处理(控件)
    • member:这个对象怎么处理(函数)
  • type:有默认值,一般不填写

QT信号也是QT对象,内部提供一些成员函数,使用时需要注意发送信号和相应的控件符合。

各种控件的信号可以看QT文档

上述的函数声明,是旧版本的QT,旧版本的QT给信号参数传参需要搭配一个SIGNAL宏
给槽函数传参需要搭配一个SLOT宏connect(button,SIGNAL(&QPushButton::clicked),this,SLOT(&QWidget::close));

eg:

#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    QPushButton*button=new QPushButton(this);
    button->setText("关闭");
    button->move(200,200);
    //点击关闭信号,this指的Widget,通过Widget来响应这个信号,&QWidget::close是QT内置的槽函数,负责控件关闭
    connect(button,&QPushButton::clicked,this,&QWidget::close);
}

Widget::~Widget()
{
    delete ui;
}

2. QT自定义信号和槽函数

自定义槽函数:

方式一:手动定义函数

#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    QPushButton*button=new QPushButton(this);
    button->setText("按钮");
    button->move(200,200);
    connect(button,&QPushButton::clicked,this,&Widget::handerClick);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::handerClick()
{
    //按下按钮,设置窗口标题
    this->setWindowTitle("按钮按下");
    qDebug()<<this->windowTitle();
}

方法二:通过ui界面生成槽函数
在这里插入图片描述
这个窗口就是QPushButton控件提供的所有信号
在这里插入图片描述

此时这个函数自动会绑定这个按钮的信号(通过函数名称来绑定,函数名为on+按钮的objectname+信号名称)egon_myButton_clicked,当函数名符合上述规则,QT会对响应控件的信号自动进行绑定(connectSlotsByName函数)
在这里插入图片描述

自定义信号:实际开发中比较少,QT内置信号基本已经覆盖控件所有操作,自定义信号一般需要程序员手动发送(emit关键字)

QT信号本质上也是函数(特殊函数,只有函数声明,并且将其声明成QT信号即可,QT编译自动生成这个信号函数)

信号函数的返回值为void,有无参数都可以。

eg:

//.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_myButton_clicked();

private:
    Ui::Widget *ui;

//自定义信号,QT扩展的关键字,在qmake扫描带这个关键字后会生成具体代码
signals:
    void mySignals();
public:
    void handMySignals();
};
#endif // WIDGET_H

//.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //关联自定义信号
    connect(this,&Widget::mySignals,this,&Widget::handMySignals);
    //初始化时发送自定义信号
    emit mySignals();
}

Widget::~Widget()
{
    delete ui;
}

void Widget::handMySignals()
{
    this->setWindowTitle("自定义信号");
}

带参数的信号和槽函数

当信号带有参数时,槽的参数必须和信号一致,此时发射信号时就可以给这个信号函数传递参数,与之对应的参数就会被传递给槽函数

//.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT //Q_OBJECT宏:在QT中让某个类能够使用信号槽机制,必须要在类最开始的地方声明这个宏。

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

//自定义信号,QT扩展的关键字,在qmake扫描带这个关键字后会生成具体代码
signals:
    void mySignals(const QString&);
public:
    void handMySignals(const QString&);
};
#endif // WIDGET_H

//.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //关联自定义信号
    connect(this,&Widget::mySignals,this,&Widget::handMySignals);
    //初始化时发送自定义信号
    emit mySignals("带参自定义信号");
}

Widget::~Widget()
{
    delete ui;
}
void Widget::handMySignals(const QString&text)
{
    this->setWindowTitle(text);
}

注意:当信号函数参数个数超过了槽函数参数个数,代码可以正常运行,信号多余的参数槽函数接受不到。反之报错

这里这样设计的原因是:信号与槽函数绑定不是一对一的,一个槽函数可能绑定多个信号,如果严格要求信号函数和槽函数参数一致,那么同一个槽函数有些信号无法绑定。使用这样的规则,信号和槽的绑定更加灵活,这样更多的信号就可以绑定到这个槽函数了。

Q_OBJECT宏:在QT中让某个类能够使用信号槽机制,必须要在类最开始的地方声明这个宏。
在这里插入图片描述

QT信号和槽机制的优点:

  1. 解耦合:触发用户的控件和处理用户的操作逻辑解耦合
  2. 一个信号可以绑定多个槽函数,一个槽函数也可以绑定多个信号(多对多,关联表)

此外可以使用disconnect函数断开信号和槽函数的连接
eg:

void Widget::on_pushButton_clicked()
{
    this->setWindowTitle("修改窗口标题");
}

void Widget::on_pushButton_2_clicked()
{
    //断开原来按钮的槽函数
    disconnect(ui->pushButton,&QPushButton::clicked,this,&Widget::on_pushButton_clicked);
    qDebug()<<"重新绑定槽函数";
    //重新绑定信号槽
    connect(ui->pushButton,&QPushButton::clicked,this,&Widget::handclick);
}

void Widget::handclick()
{
    this->setWindowTitle("重新修改窗口标题");
}

此外,在定义槽函数时也可以使用lambda表达式,其本质就是匿名函数,常常用于回调函数

eg:

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    QPushButton*button=new QPushButton(this);
    button->setText("按钮");
    int* times=new int(1); //这里必须new 因为这是在构造函数中connect的,设计变量声明周期问题,new出的变量必须手动释放,变相提高了声明周期,使得connect函数捕获times指针解引用不会报错
    //lambda作为回调函数
    connect(button,&QPushButton::clicked,this,[=](){
        qDebug()<<"lambda回调函数";
        //点击按钮移动按钮
        button->move(10*(*times),10*(*times));
        *times+=1;
    });
    emit signals1();
    emit signals2();

}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

学习ArkTS -- 状态管理

装饰器 State 在声明式UI中&#xff0c;是以状态驱动试图更新&#xff1a; 状态&#xff08;State&#xff09;&#xff1a;指驱动视图更新的数据&#xff08;被装饰器标记的变量&#xff09; 视图&#xff08;View&#xff09;&#xff1a;基于UI描述渲染得到用户界面 说明…

汕头联想 ibm x3500 M5服务器上门维修记录

汕头联想服务器现场检修&#xff1b;汕尾IBM服务器故障维修&#xff1b;揭阳戴尔服务器维修&#xff1b;汕头ERP服务器维修&#xff1b;潮阳地区各种服务器故障维修&#xff1b;各类服务器主板齐全&#xff1b; 分享一例从东莞到汕头某染料厂维修ibm system x3500 M5服务器的真…

LocalAi,Ollama+AnythingLLM搭建部署本地大模型AI知识库,汉化版本

AnythingLLM 是一个全栈应用程序&#xff0c;您可以使用商业现成的 LLM 或流行的开源 LLM 和 vectorDB 解决方案来构建私有 ChatGPT&#xff0c;无需任何妥协&#xff0c;您可以在本地运行&#xff0c;也可以远程托管并能够智能聊天以及您提供的任何文件。 AnythingLLM 将您的文…

UI5:面向企业级应用的JavaScript框架

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

vue的学习之用vue写一个hello,vue

根据以下步骤下载vue.js 介绍 — Vue.js 创建一个damo.html &#xff0c;引入vue.js即可 <body><div id"app">{{ message }}</div><!-- Vue --><!-- 开发环境版本&#xff0c;包含了有帮助的命令行警告 --><script src"js/vu…

苹果电脑装虚拟机好用吗 苹果电脑装虚拟机要钱吗 Parallels对mac的损害 Parallels占用多大空间 PD19

在当今数字化的时代&#xff0c;人们对电脑系统跨设备互联的需求越来越高。作为拥有广泛用户群体的苹果电脑&#xff0c;许多用户会有在Mac系统中运行其他操作系统的需求。在这种情况下&#xff0c;安装虚拟机是一个较好的解决方案。那么接下来就给大家介绍苹果电脑装虚拟机好用…

{“errMsg“:“insertXWebCamera:fail appid privacy api banned“}

问题描述&#xff1a;微信小程序&#xff0c;在体验版本测试时&#xff0c;调用摄像头OK&#xff0c;没有任何问题&#xff0c;部署发布版本后&#xff0c;日志报错内容&#xff1a;{"errMsg":"insertXWebCamera:fail appid privacy api banned"}&#xff…

企业公众号数量怎么申请

一般可以申请多少个公众号&#xff1f;许多用户在申请公众号时可能会遇到“公众号显示主体已达上限”的问题。这是因为在2018年11月16日对公众号申请数量进行了调整&#xff0c;具体调整如下&#xff1a;1、个人主体申请公众号数量上限从2个调整为1个。2、企业主体申请公众号数…

那些早期的iax和SIP软电话软件界面,看看你见过几个?

目录 一些iax/sip软电话UI图片SIP软电话的界面怎么设计SIP软电话的功能有哪些 早期voip发展中&#xff0c;很多公司开发了自己的SIP软电话&#xff0c;有些已经不存在了&#xff0c;有些还在使用中&#xff0c;比如X-Lite&#xff0c;Zoiper等等&#xff0c;我们一起看看这些早…

【软考经验分享】软考-中级-嵌入式备考

这里写目录标题 教辅用书嵌入式系统设计师考试大纲嵌入式系统设计师教程嵌入式系统设计师5天修炼嵌入式系统设计师考前冲刺100题 刷题软件希赛网软考真题 视频教程希赛网王道-计组计网 教辅用书 嵌入式系统设计师考试大纲 50页左右&#xff0c;内容为罗列一些考点&#xff0c…

C语言(扫雷游戏)

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸各位能阅读我的文章&#xff0c;诚请评论指点&#xff0c;关注收藏&#xff0c;欢迎欢迎~~ &#x1f4a5;个人主页&#xff1a;小羊在奋斗 &#x1f4a5;所属专栏&#xff1a;C语言 本系列文章为个人学习笔记&#x…

基于docker搭建瀚高数据库HighGo6.0.1【图文】

基于docker搭建瀚高数据库HighGo6.0.1 拉取镜像启动验证进入容器 登录数据库查看数据库加密方式修改加密方式为sm3进入数据库修改密码重启容器 数据库验证数据库密码到期参考 docker部署 https://blog.csdn.net/weixin_44385419/article/details/127738868 拉取镜像 docker p…

Springboot+Vue项目-基于Java+MySQL的网上点餐系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

[XR806开发板试用]MQ-2烟雾传感器

非常感谢这次极术社区给我这个机会直接接触harmonyos&#xff0c;日常接触的一般都是恩智浦的I.MX RT系列比较多&#xff0c;对于这一类高速汽车芯片来说&#xff0c;最常接触的是RThread系统比较多。而且相对编译环境比较容易配置&#xff0c;直接接触这类系统还是第一次&…

【Qcom Camera】DumpDebugInfo分析

DumpDebugInfo&#xff1a; DumpDebugInfo主要包括Session::DumpDebugInfo、Pipeline::Dumpdebuginfo、Node::Dumpdebuginfo、DRQ::Dumpdebuginfo、Usecase::DumpDebugInfo log&#xff1a;Hit SOF threshold of [xx] consecutive frames CamX: [ERROR][CORE ] camxpip…

1.基于Springboot对SpringEvent初步封装

一&#xff1a;前置知识 Spring Event是Spring框架提供的一种事件机制&#xff0c;用于处理组件之间的通信。在复杂的系统中&#xff0c;模块或组件之间的通信是必不可少的。Spring Event可以用于以下场景&#xff1a; 1.系统间解耦&#xff1a;模块或组件之间通过事件进行通…

就业班 第三阶段(负载均衡) 2401--4.19 day3 nginx3

二、企业 keepalived 高可用项目实战 1、Keepalived VRRP 介绍 keepalived是什么keepalived是集群管理中保证集群高可用的一个服务软件&#xff0c;用来防止单点故障。 ​ keepalived工作原理keepalived是以VRRP协议为实现基础的&#xff0c;VRRP全称Virtual Router Redundan…

跨语言大模型最新综述

节前&#xff0c;我们星球组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、参加社招和校招面试的同学&#xff0c;针对算法岗技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备、面试常考点分享等热门话题进行了深入的讨论。 汇总…

L2-052 吉利矩阵

题目描述 题解思路 这个道题就是很简单&#xff0c;就跟n皇后问题一样&#xff0c;给矩阵填数&#xff0c;使得矩阵满足一个什么条件&#xff0c;最后求方案数或者方案。很容易想到回溯法&#xff0c;根据数据范围&#xff0c;应该能够确定回溯法是没有问题的。 我们只需要枚举…

《C语言深度解剖》(9):深度剖析数据在内存中的存储

&#x1f921;博客主页&#xff1a;醉竺 &#x1f970;本文专栏&#xff1a;《C语言深度解剖》 &#x1f63b;欢迎关注&#xff1a;感谢大家的点赞评论关注&#xff0c;祝您学有所成&#xff01; ✨✨&#x1f49c;&#x1f49b;想要学习更多数据结构与算法点击专栏链接查看&am…