首页 > 其他分享 >Qt 信号与槽

Qt 信号与槽

时间:2023-03-06 21:11:51浏览次数:40  
标签:Qt 自定义 QObject connect 信号 函数

Qt 信号与槽

目录

参考:【Qt】一篇全面的信号和槽函数机制总结_iriczhao的博客-CSDN博客_qt 信号和槽的机制

信号与槽的概念

Qt的信号与槽机制概述

信号和槽机制是Qt的核心特性,用于多个对象之间的通信。Qt的元对象(meta)机制是信号和槽实现的基础

特点:

  1. 信号和槽机制是类型安全的:信号的参数必须与接收槽函数的参数相匹配。(实际上,槽的参数可以比它接收到的信号参数更少,因为槽可以忽略额外的参数)
  2. 信号和槽函数是松耦合的:当一个对象发出信号,该对象不知道也不关心哪个对象的槽函数会接收该信号。Qt的信号和槽函数机制确保:如果将一个信号连接到一个槽函数上,该槽函数将在正确的时间被调用。
  3. 可以将多个信号连接到一个槽函数上(即【多对一】),而一个信号也可以连接到多个槽函数上【即一对多】

信号函数

  • 可以重载
  • 定义在某个类中,该类直接或间接继承自 QObject 类,且添加 Q_OBJECT【激活元对象机制】
  • signals 关键字修饰;
  • 信号函数只需要声明,不需要定义(实现),实现是由QT的moc工具自动完成的;
  • 信号函数的返回值类型必须为 void,参数的类型和个数不限。

在Qt框架下,信号发出分为两种:

  1. 【每个类预定义的信号】:这些信号何时发出可以通过查看官方文档获知。

  2. 【自定义的信号】:这些信号的发出由开发人员自行定义。

在此讲解自定义信号。

信号的定义

示例:

class MyWidget:public QWidget{
    //Q_OBJECT 是一个宏,添加它才能正常使用 Qt 的信号和槽机制
    Q_OBJECT
//信号函数
signals:
    //自定义的信号函数
    void MySignal(QString message);
};

信号的发射

信号可以从任何地方发出,但是建议:【只从定义该信号的类及其子类发出信号】

对于 Qt 提供给我们的信号函数,其底层已经设置好了信号发出的时机,例如按下鼠标时、点击 Enter 回车键时等等。

对于自定义的信号,我们需要自己指定信号发出的时机,需要使用 emit 关键字,专门用来发射信号。

可以在任何地方emit发射信号,不一定要在信号函数的函数体内。

用法是在自定义信号函数的函数体内使用 emit 关键字发射信号,格式如下:

emit 自定义信号函数(自定义信号函数的实参列表);

示例:

class MyWidget:public QWidget{
    //Q_OBJECT 是一个宏,添加它才能正常使用 Qt 的信号和槽机制
    Q_OBJECT
//自定义信号函数
signals:
    void MySignal(QString mess);
public:
    void emitSignal(){
        emit MySignal(message);//使用emit发射自定义信号
    }
private:
    QString message;
};

注意

emit语句之后的代码将在所有槽函数都返回之后才执行。如果使用排队连接,情况略有不同,在这种情况下,emit关键字后面的代码将立即继续,槽函数将稍后执行。

槽函数

槽函数是普通的C++成员函数,当一个连接到槽函数的信号被发射时,槽函数将被调用;由于槽是普通的成员函数,所以它们在直接调用时遵循普通的C++规则。但是作为槽函数时,任何组件都可以通过信号连接从而调用它们。

  • 可以重载
  • 可以使用slot关键字声明槽函数,Qt5之后可以不用
  • 信号可以与它们相连接
  • 需要手动实现
  • 返回值必须与所要响应的信号函数相同
  • 参数顺序必须与信号函数相同
  • 参数可以从后往前减少,当然也可以减少到没有参数【即参数个数小于等于信号函数的参数】

示例:

class MyWidget:public QWidget{
    //Q_OBJECT 是一个宏,添加它才能正常使用 Qt 的信号和槽机制
    Q_OBJECT
//信号函数
signals:
    //自定义的信号函数
    void MySignal(QString message);
//槽函数
public slots:
    void recSlot2(QString mess1,QString mess2){
        qDebug() << "执行 recSlot2() 槽函数,输出"<< mess1 << " " << mess2;
    }
};

槽函数与信号函数的连接

1、使用Qt设计师

详见:Qt 默认静态槽函数 connectSlotsByName浅析 - 3的4次方 - 博客园 (cnblogs.com)

2、使用 QObject::connect()

函数原型:

//connect(信号的发送者,信号的具体信息,信号的接受者,信号的处理[槽])
[static] QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection)

(1)第一种方法:使用QObject::connect()以及信号和槽声明宏。

在Qt4中,使用 SIGNAL() 宏声明信号,SLOT() 宏声明槽。

SIGNAL()SLOT()宏中包含参数的规则是:传递给SIGNAL()宏的参数不能少于传递给SLOT()宏的参数

  • 优点:信号和槽参数很直观

  • 缺点:使用宏,编译时不做类型检查,只能在运行时发现错误

以下合法:

connect(sender, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(Qbject*)));
connect(sender, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed()));
connect(sender, SIGNAL(destroyed()), this, SLOT(objectDestroyed()));

以下不合法:

connect(sender, SIGNAL(destroyed()), this, SLOT(objectDestroyed(QObject*)));

(2)第二种方法:使用C++11的lambda函数【即使用函数对象】

connect(sender, &QObject::destroyed, this, [=](){ this->m_objects.remove(sender); });

在这两种情况下,我们在connect()调用中提供这个上下文。上下文对象提供关于应该在哪个线程中执行接收器的信息。

当发送方或上下文被销毁时,lambda将断开连接。注意:当信号发出时,函数内部使用的所有对象依然是激活的。

  • 优点:代码简洁

(3)第三种方法:使用函数指针。

在Qt5中,可以使用函数指针取代宏。

connect(sender, &QObject::destroyed, this, &MyObject::objectDestroyed);
  • 优点:允许编译器检查信号的参数是否与槽的参数兼容。如果需要,编译器还可以隐式地转换参数

  • 缺点:无法识别函数重载的情况

Qt预定义的信号与槽

在对应的控件的Qt助手文档中的 Signal Documentation 栏下面有罗列

标签:Qt,自定义,QObject,connect,信号,函数
From: https://www.cnblogs.com/3to4/p/17185458.html

相关文章

  • Qt 默认静态槽函数 connectSlotsByName浅析
    Qt默认静态槽函数connectSlotsByName浅析Qt中生成槽函数的方式在Qt中有3种生成槽函数的方式:第一种就是手动写connect连接函数,函数原型如下://connect(信号的发送者,......
  • Qt音视频开发20-vlc内核动态保存录像文件(不需要重新编译源码)
    一、前言在vlc默认提供的保存文件方式中,通过打开的时候传入指定的参数来保存文件,直到关闭播放生成文件,这种方式简单暴力,但是不适用大部分的场景,大部分时候需要的是提供开......
  • qtav播放采集卡
    打印提示这个,"[email protected]:282907.014"搜索代码qDebug("delay%fs@%.3fspts:%.3f",diff,d.clock->value(),pkt.pts);F:\qt-project\QtAV\src\V......
  • QT主窗口关闭,同时关闭打开的子窗体
    1、主窗口关闭,主窗口上的dock窗口不需要特殊处理也会关闭,直接退出主程序。2、主窗口关闭,需要在所有子窗口(单独new出来的非dock窗口)的构造函数中添加代码 this->setAttrib......
  • Pycharm配置pyqt5
    关于PyQt5,在pycharm上的安装步骤及使用技巧(最重要)https://www.cnblogs.com/pywjh/p/9835931.html importsysfromPyQt5.QtWidgetsimportQApplication,QMainWindowf......
  • 信号的直流分量与交流分量求解|信号分解
    一、直流分量是什么意思?1.定义:直流分量是指信号中的直流成分,信号的直流分量就是信号的平均值,它是一个与时间无关的常数。如果原信号是周期信号,在用数学公式表达时可以省......
  • qt中文件读一行操作
     windows平台下也就是回车换行。此外:QT帮助文档中对QIODevice::Text描述是说在读取时,将行结束符转换成\n;在写入时,将行结束符转换成本地格式,例如Win32平台上是\r\n......
  • Qt学习笔记 - 第一章 - 快速开始、信号与槽
    Qt学习笔记全系列传送门:【本章】Qt学习笔记-第一章-快速开始、信号与槽Qt学习笔记-第二章-添加图片、布局、界面切换目录1、Qt工程创建2、工程文件......
  • QT QTableWidget 设置每一列的宽度(大概可以实现)
    //第一个参数代表:第几列,第二个参数:代表要进行的操作(对内容进行调整,或者,添加拉伸达到拉长表格的效果)ui->tableWidget->horizontalHeader()->setSectionResizeMode(......
  • 数字信号处理流程
    数字信号处理是指将连续时间的信号(模拟信号)转换为离散时间的信号,并对其进行数字处理的技术。其处理流程可以分为以下几个步骤:采样(Sampling):将连续时间的信号在时间上进行......