1. 发送一次信号,调用多次槽函数问题
在同一个类中,多次链接QObject::connect(sender, SIGNAL(signalSender(QString, int)), receiver, SLOT(onSignalSender(QString, int))); 会导致发送一次信号signalSender(QString, int) 多次调用槽函数(onSignalSender(QString, int),如果链接了一次,那么,发送一次signalSender信号,就调用一次onSignalSender槽函数,如果链接了两次,那么发送一次signalSender信号,就调用两次onSignalSender槽函数,。。。以此类推。
2. 信号的直接调用问题
在Qt中,一般发送信号都是通过 emit signalSender() 方式发送的,其实也可以通过直接调用信号 signalSender()进行发送,此时,如果调用了信号signalSender,且该信号通过connect进行了链接,则会进入对用链接的槽函数中执行。 注意:在多线程中,直接调用是在调用者线程中执行,发信号是在接收者线程中执行
3.
信号是可以连接另一个信号的
例如
connect(push_button, &qpushlbutton::clicked, this, & qwidget :: buttonclicked );
Qt信号与信号连接、Qt4连接写法
1.信号与信号连接
更改代码
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QPushButton>
//Teacher类
//Student类
//下课后老师会触发一个信号(饿了),学生响应信号(请客吃饭)
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//创建一个老师的对象
this->th = new Teacher();
//创建一个学生的对象
this->stu = new Student();
//重载连接,需要用到函数指针,指向明确的函数地址
//无参函数连接,两种写法
void(Teacher::* teacherSignal0)() = &Teacher::hungry;
void(Student::* studentSlot0)(void) = &Student::treat;
connect(th,teacherSignal0,stu,studentSlot0);
//有参连接
void(Teacher::* teacherSignal)(QString) = &Teacher::hungry;
void(Student::* studentSlot)(QString) = &Student::treat;
connect(th,teacherSignal,stu,studentSlot);
//点击叮叮叮按钮,再触发下课
QPushButton* btn = new QPushButton("叮叮叮",this);
//第一种实现
//connect(btn,&QPushButton::clicked,this,&Widget::classIsOver);
//第二种实现
//信号连接信号
connect(btn,&QPushButton::clicked,th,teacherSignal0);
resize(400,400);
}
void Widget::classIsOver()
{
//下课函数,触发后发送老师饿了的信号
//emit出发信号 qt独有语法
emit th->hungry();
emit th->hungry("昏睡红茶");
qDebug() << "------------";
}
Widget::~Widget()
{
delete ui;
}
注意:信号连接时,信号与槽的参数必须一一对应。不然会报static assertion failed: Signal and slot arguments are not compatible.
的bug。
扩展内容
- 一个信号可以连接多个槽函数
- 多个信号可以连接一个槽函数
- 信号和槽函数的参数必须一一对应
- 信号参数个数可以多余槽的参数个数,但类型要一一对应
Qt4版本以前的信号与槽的连接
连接无参
connect(th,SIGNAL(hungry()),stu,SLOT(treat()));
优点,参数直观。缺点,类型不做检测(编译不做检测,运行报错)
Qt5以上支持Qt4的写法,反之不支持。
qt, connect参数,Qt::DirectConnection,Qt::QueuedConnection
connect用于连接qt的信号和槽,在qt编程过程中不可或缺。它其实有第五个参数,只是一般使用默认值,在满足某些特殊需求的时候可能需要手动设置。
Qt::AutoConnection: 默认值,使用这个值则连接类型会在信号发送时决定。如果接收者和发送者在同一个线程,则自动使用Qt::DirectConnection类型。如果接收者和发送者不在一个线程,则自动使用Qt::QueuedConnection类型。
Qt::DirectConnection:槽函数会在信号发送的时候直接被调用,槽函数运行于信号发送者所在线程。效果看上去就像是直接在信号发送位置调用了槽函数。这个在多线程环境下比较危险,可能会造成奔溃。
Qt::QueuedConnection:槽函数在控制回到接收者所在线程的事件循环时被调用,槽函数运行于信号接收者所在线程。发送信号之后,槽函数不会立刻被调用,等到接收者的当前函数执行完,进入事件循环之后,槽函数才会被调用。多线程环境下一般用这个。
Qt::BlockingQueuedConnection:槽函数的调用时机与Qt::QueuedConnection一致,不过发送完信号后发送者所在线程会阻塞,直到槽函数运行完。接收者和发送者绝对不能在一个线程,否则程序会死锁。在多线程间需要同步的场合可能需要这个。
Qt::UniqueConnection:这个flag可以通过按位或(|)与以上四个结合在一起使用。当这个flag设置时,当某个信号和槽已经连接时,再进行重复的连接就会失败。也就是避免了重复连接。
来源:oschina
链接:https://my.oschina.net/u/4265014/blog/4520448