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操作法
- 选中控件点击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