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

QT的信号槽的直接触发,队列触发,自动触发

在Qt中,信号槽机制是一个非常强大的特性,它用于实现对象之间的通信。除了默认的直接触发方式之外,Qt还提供了队列触发等不同的触发方式。

1. 直接触发(Direct Connection)

直接触发是最常见的连接方式,信号发射后,槽函数会立即执行。它通常用于发信号和接收槽都在同一个线程时。

#include <QObject>
#include <QDebug>

class Sender : public QObject {
    Q_OBJECT
public:
    void sendSignal() {
        emit signal1();
    }
signals:
    void signal1();
};

class Receiver : public QObject {
    Q_OBJECT
public slots:
    void slot1() {
        qDebug() << "Signal received directly, Slot executed!";
    }
};

int main() {
    Sender sender;
    Receiver receiver;

    QObject::connect(&sender, &Sender::signal1, &receiver, &Receiver::slot1, Qt::DirectConnection);
    
    sender.sendSignal();  // Will directly call slot1
}
在这个例子中,signal1 信号触发时,槽函数 slot1 会立即执行,属于直接连接。

2. 队列触发(Queued Connection)

队列触发适用于发信号和接收槽在不同线程时。此时,信号会被放入接收线程的事件队列中,槽函数会在接收线程的事件循环中执行。这样能避免直接跨线程调用导致的问题。

#include <QObject>
#include <QDebug>
#include <QThread>

class Sender : public QObject {
    Q_OBJECT
public:
    void sendSignal() {
        emit signal1();
    }
signals:
    void signal1();
};

class Receiver : public QObject {
    Q_OBJECT
public slots:
    void slot1() {
        qDebug() << "Signal received via queue, Slot executed!";
    }
};

int main() {
    QThread thread;
    Sender sender;
    Receiver receiver;

    receiver.moveToThread(&thread);  // Move receiver to another thread
    thread.start();

    QObject::connect(&sender, &Sender::signal1, &receiver, &Receiver::slot1, Qt::QueuedConnection);

    sender.sendSignal();  // Slot will be executed in receiver's thread

    thread.quit();
    thread.wait();
}
在这个例子中,由于 SenderReceiver 在不同的线程中,信号 signal1 会被放入接收线程的事件队列中,等到事件循环执行时,槽函数 slot1 才会被调用。

3. 自动触发(Auto Connection)

这是 Qt 的默认行为,Qt 会自动选择直接触发或队列触发的方式,取决于信号和槽是否在同一个线程中。如果在同一个线程,直接触发;如果在不同的线程,则使用队列触发。

#include <QObject>
#include <QDebug>
#include <QThread>

class Sender : public QObject {
    Q_OBJECT
public:
    void sendSignal() {
        emit signal1();
    }
signals:
    void signal1();
};

class Receiver : public QObject {
    Q_OBJECT
public slots:
    void slot1() {
        qDebug() << "Signal received (auto connection), Slot executed!";
    }
};

int main() {
    QThread thread;
    Sender sender;
    Receiver receiver;

    receiver.moveToThread(&thread);  // Move receiver to another thread
    thread.start();

    QObject::connect(&sender, &Sender::signal1, &receiver, &Receiver::slot1);  // Default auto connection

    sender.sendSignal();  // Will use Qt's auto connection (queued because they are in different threads)

    thread.quit();
    thread.wait();
}

在这个例子中,QObject::connect 没有明确指定连接类型,Qt 会自动选择适当的连接方式(在不同线程时,默认会使用队列触发)。

总结

  • 直接触发:信号发射后,槽函数立即执行(通常用于同一线程)。

  • 队列触发:信号被放入接收线程的事件队列,槽函数在事件循环中执行(通常用于跨线程)。

  • 自动触发:Qt会根据线程关系自动选择触发方式。

相关文章:

  • # 使用python写一个PDF文件转换成word 文件
  • 【Linux 并发与竞争实验】
  • Python自学第1天:变量,打印,类型转化
  • FoundationPose 4090部署 真实场景迁移
  • 聊聊 JUC 下的 CountDownLatch、CyclicBarrier、Phaser 和 Semaphore
  • 一次引入第三方库导致的权限崩溃
  • 【YOLOv8改进- Backbone主干】CVPR2025 MambaOut :为图像分类任务设计的轻量级模型,曼巴永存!
  • std::map gdb调试ok ,直接运行会crash
  • 如何用 esProc 补充数据库 SQL 的缺失能力
  • 湖南(源点咨询)市场调研 商业综合体定位调研分享(中篇)
  • mapstruct使用详解
  • 12.第二阶段x64游戏实战-远程调试
  • 美团一面总结
  • list的一些常用接口
  • 流量统计实例
  • 域AD渗透手法【密码喷洒技术】
  • 【JavaScript】二十三、M端事件 + 轮播图Swiper插件
  • USB(TYPE-C)转串口(TTL)模块设计讲解
  • C++之 动态数组
  • 河南普瑞维升企业案例:日事清SOP流程与目标模块实现客户自主简报功能落地
  • 诗词门户网站/我想接app注册推广单
  • 购物网站建设需求/百度首页优化
  • 网站排名软件网址/长春seo快速排名
  • 开发网页系统一般多少钱/seo信息网
  • 自家电脑做网站/北京网络seo经理
  • 广州沙河一起做网站/seo搜索优化邵阳