QT信号槽机制原理

QT信号与槽连接的五种方法

第一种方法

复制代码
 QT4写法
connect(ui->btnOpen, SIGNAL(clicked), this, SLOT(open()))

不推荐这种方法,如果SIGNAL写错了、或者信号名称、槽函数名称写错了,编译器检查不出来,导致程序无响应

第二种方法

QT5写法

connect(ui->btnOpen, &QPushButton::clicked, this, &Widget::open))

推荐这种方法,如果信号名称、槽函数名称写错了,编译器会报错提醒

第三种方法

槽函数用lamda表达式实现

connect(ui->btnOpen, &QPushButton::clicked, this, =

{

xxxx

})

适用于槽函数逻辑相对较少场景

第四种方法

UI操作法

  1. 选中控件点击Edit Signals/Slots

2、

  • 点击控件拖到到QWidget上去,即如下步骤2
  • 选择QPushButton控件的clicked信号,然后选中QWidget的信号槽编译
  • 手动添加槽函数,如下图中槽函数名为slots
  • 点击ok确定

最后代码中写出对应槽函数slots实现

第五种方法

假如一个QPushButton控件的objectname为btn2

,那么我们只需要写一个槽函数为,on_btn2_clicked(),格式为on_obejctname_信号名称即可,QT会自动进行信号与槽绑定,不需要显示调用connect进行绑定,是qt中自动绑定连接方式

解决信号重名问题


bash 复制代码
    ui->comboBox->addItem("item1");
    ui->comboBox->addItem("item2");
    ui->comboBox->addItem("item3");
    ui->comboBox->addItem("item4");

    connect(ui->comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &Widget::currentIndexChanged_int);
    connect(ui->comboBox, QOverload<const QString&>::of(&QComboBox::currentIndexChanged), this, &Widget::currentIndexChanged_str);

void Widget::currentIndexChanged_str(const QString &text)
{
    qDebug() << "current index changed text: " << text;
}

void Widget::currentIndexChanged_int(int index)
{
    qDebug() << "current index changed index: " << index;
}

connect参数详解

其中第五个参数ConnectionType有5个取值

  • AutoConnection:根据发送方和接收方是否在同一个线程中,如果在同一个线程中使用Qt::DirectConnection,否则使用Qt::QueuedConnection
  • DirectConnection:信号发出后,槽函数会‌立即‌在发出信号的线程中被调用,就像一个普通的函数调用。这在同一线程内是高效的,但在跨线程时极不安全
  • QueuedConnection:信号发出后,会创建一个事件并将其放入‌接收者对象所在线程‌的事件队列中。槽函数会在该线程的事件循环下次轮询到此事件时才被执行,因此是‌异步‌的
  • BlockingQueuedConnection:和QueuedConnection流程基本相同,不同的是该类型是同步的,发送信号的线程会阻塞等待直到槽函数被调用,所以该连接类型不能应用在发送方和接收方在同一个线程的场景下,会导致死锁出现。
  • UniqueConnection:不经常使用

Moc元对象编译器

MOC:Meta-Object Compiler元对象编译器

原理:QT程序在标准编译器编译前,会先通过MOC分析C++源文件,如果在头文件中包含了Q_OBJECT宏定义,则会生成另外一个C++源文件,该文件的名称格式moc_类名.cpp,

这个cpp文件会被程序进行编译进最后的可执行二进制文件中去。

其中moc工具路径在E:\Tools\qt\Qt5\5.14.2\msvc2017_64\bin\moc.exe

相关推荐
ShineWinsu5 小时前
对于C++:继承的解析—上
开发语言·数据结构·c++·算法·面试·笔试·继承
小付同学呀5 小时前
C语言学习(五)——输入/输出
c语言·开发语言·学习
梦幻精灵_cq5 小时前
学C之路:不可或缺的main()主函数框架(Learn-C 1st)
c语言·开发语言
消失的旧时光-19436 小时前
C++ 多线程与并发系统取向(二)—— 资源保护:std::mutex 与 RAII(类比 Java synchronized)
java·开发语言·c++·并发
福大大架构师每日一题7 小时前
go-zero v1.10.0发布!全面支持Go 1.23、MCP SDK迁移、性能与稳定性双提升
开发语言·后端·golang
五阿哥永琪7 小时前
1. 为什么java不能用is开头来做布尔值的参数名,会出现反序列化异常。
java·开发语言
逻极8 小时前
pytest 入门指南:Python 测试框架从零到一(2025 实战版)
开发语言·python·pytest
你的冰西瓜8 小时前
C++ STL算法——排序和相关操作
开发语言·c++·算法·stl
海边的Kurisu9 小时前
Mybatis-Plus | 只做增强不做改变——为简化开发而生
java·开发语言·mybatis
浅念-9 小时前
C++ 模板进阶
开发语言·数据结构·c++·经验分享·笔记·学习·模版