Windows图形界面(GUI)-QT-C/C++ - QT信号与槽机制详解

目录

Qt消息机制概述

什么是信号与槽

基本概念

信号(Signals)详解

信号的特征

信号的定义方式

槽(Slots)详解

槽的特征

槽的定义方式

信号与槽的连接

基本连接语法

连接类型

高级特性

信号与槽的重载处理

高级连接特性


Qt消息机制概述

什么是信号与槽

++Qt的信号与槽(Signals & Slots)是Qt框架中最特殊和最重要的特性之一,它提供了对象之间的通信机制。这种机制比传统的回调函数更加安全和灵活。++

基本概念

  • 信号(Signals): 当对象状态发生改变时发出的通知
  • 槽(Slots): 响应信号的函数
  • 连接(Connection): 信号和槽之间建立的关联

信号(Signals)详解

信号的特征

  1. 声明位置:signals关键字下
  2. 访问权限:默认protected
  3. 返回类型:必须是void
  4. 参数特点:可以有任意参数
  5. 实现特点:只需声明,无需实现

信号的定义方式

cpp 复制代码
class QMySignal : public QObject  
{  
    Q_OBJECT  
public:  
    explicit QMySignal(QObject *parent = nullptr);  

signals:  
    void dataChanged();                 // 无参数信号  
    void valueChanged(int value);       // 带参数信号  
    void statusChanged(QString status, int code); // 多参数信号  
    
public:  
    void triggerSignal()  
    {  
        emit dataChanged();  // 发射信号  
    }  
};

槽(Slots)详解

槽的特征

  1. 声明位置:可在public slots、protected slots或private slots下
  2. 访问权限:根据声明位置确定
  3. 返回类型:通常为void,但可以有返回值
  4. 参数要求:需与信号参数匹配

槽的定义方式

cpp 复制代码
class QMySlot : public QObject  
{  
    Q_OBJECT  
public:  
    explicit QMySlot(QObject *parent = nullptr);  

public slots:  
    void handleData()  
    {  
        qDebug() << "Data received";  
    }  
    
    void handleValue(int value)  
    {  
        qDebug() << "Value:" << value;  
    }  
    
    void handleStatus(QString status, int code)  
    {  
        qDebug() << "Status:" << status << "Code:" << code;  
    }  
};

信号与槽的连接

基本连接语法

cpp 复制代码
// 基本连接方式  
connect(sender, SIGNAL(signalName()), receiver, SLOT(slotName()));  

// 新式语法(推荐)  
connect(sender, &Sender::signalName, receiver, &Receiver::slotName);

连接类型

cpp 复制代码
// 直接连接  
connect(sender, &Sender::signal, receiver, &Receiver::slot,   
        Qt::DirectConnection);  

// 队列连接(跨线程)  
connect(sender, &Sender::signal, receiver, &Receiver::slot,   
        Qt::QueuedConnection);  

// 唯一连接  
connect(sender, &Sender::signal, receiver, &Receiver::slot,   
        Qt::UniqueConnection);

高级特性

信号与槽的重载处理

cpp 复制代码
// 1. 使用函数指针  
void (MyClass::*mySignal)(int) = &MyClass::mySignal;  
connect(sender, mySignal, receiver, mySlot);  

// 2. 使用static_cast  
connect(sender,   
        static_cast<void(MyClass::*)(int)>(&MyClass::mySignal),  
        receiver,   
        static_cast<void(MyClass::*)(int)>(&MyClass::mySlot));  

// 3. 使用QOverload(Qt 5.7+)  
connect(sender,  
        QOverload<int>::of(&MyClass::mySignal),  
        receiver,  
        QOverload<int>::of(&MyClass::mySlot));

高级连接特性

  1. 一对多连接:一个信号可以连接多个槽
  2. 多对一连接:多个信号可以连接同一个槽
  3. 信号对信号:信号可以连接到另一个信号
cpp 复制代码
// 一对多连接示例  
connect(button, &QPushButton::clicked, this, &Widget::slot1);  
connect(button, &QPushButton::clicked, this, &Widget::slot2);  

// 信号连接信号  
connect(button1, &QPushButton::clicked, button2, &QPushButton::click);
相关推荐
学地理的小胖砸18 分钟前
【Python 基础语法】
开发语言·python
Dream it possible!23 分钟前
LeetCode 热题 100_只出现一次的数字(96_136_简单_C++)(哈希表;哈希集合;排序+遍历;位运算)
c++·leetcode·位运算·哈希表·哈希集合
IT专业服务商28 分钟前
联想 SR550 服务器,配置 RAID 5教程!
运维·服务器·windows·microsoft·硬件架构
海尔辛30 分钟前
学习黑客5 分钟小白弄懂Windows Desktop GUI
windows·学习
ŧ榕树先生36 分钟前
查看jdk是否安装并且配置成功?(Android studio安装前的准备)
java·jdk
未来的JAVA高级开发工程师40 分钟前
适配器模式
java
gushansanren42 分钟前
基于WSL用MSVC编译ffmpeg7.1
windows·ffmpeg
LUCIAZZZ1 小时前
JVM之内存管理(一)
java·jvm·spring·操作系统·springboot
D_aniel_1 小时前
排序算法-计数排序
java·排序算法·计数排序
极小狐1 小时前
极狐GitLab 通用软件包存储库功能介绍
java·数据库·c#·gitlab·maven