Qt信号槽问题汇总

核能气质少年 提交于 2020-10-26 00:05:03

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。
在这里插入图片描述


扩展内容

  1. 一个信号可以连接多个槽函数
  2. 多个信号可以连接一个槽函数
  3. 信号和槽函数的参数必须一一对应
  4. 信号参数个数可以多余槽的参数个数,但类型要一一对应

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设置时,当某个信号和槽已经连接时,再进行重复的连接就会失败。也就是避免了重复连接。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!