Qt信号和槽

1.信号和槽扫盲

(1)当信号发出后,先执行槽函数,在执行信号后面的函数(单线程)。

(2)当信号与多个槽函数连接时,按照connect的连接顺序进行执行。

上面的图片中,发出downloadFile()信号后,会依次执行onDownloadFile2() 、onDownloadFile3() 、onDownloadFile1() 

(3)信号和槽只是在代码形式上进行了分离,本质上仍按顺序执行调用函数。

2.信号和槽的高级用法

(1)获取信号发出者:sender()

当前窗口有上传和下载两个按钮,当按下他们时候获取信号发出者以及文本:

代码展示:

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    connect(ui->btnUpload,SIGNAL(clicked()),this,SLOT(onButtonClicked()));
    connect(ui->btnDownload,SIGNAL(clicked()),this,SLOT(onButtonClicked()));
}

Widget::~Widget()
{
    delete ui;
}

void Widget::onButtonClicked()
{
    //获取信号发出者
    QPushButton* button = dynamic_cast<QPushButton*>(sender());
    //获取文本
    qDebug() <<button->text();
}

(2)断开连接:disconnect()

bool QObject::disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)

演示连接的信号和槽:

connect(ui->btnUpload,SIGNAL(clicked()),this,SLOT(onButtonClicked()));
connect(ui->btnDownload,SIGNAL(clicked()),this,SLOT(onButtonClicked()));

断开所有连接:后面三个参数全部设为nullptr

//写法一
disconnect(ui->btnUpload,nullptr,nullptr,nullptr);
//写法二
ui->btnUpload->disconnect(nullptr,nullptr,nullptr);

断开指定信号的所有连接:后面两个参数设为nullptr

 disconnect(ui->btnUpload,SIGNAL(clicked()),nullptr,nullptr);

断开接受者的所有连接:

disconnect(ui->btnUpload,nullptr,this,nullptr);

 断开接收者的某个槽函数连接:

disconnect(ui->btnUpload,nullptr,this,SLOT(onButtonClicked()));

(3)QSignalMapper 

 使用QSignalMapper 来匹配信号发送,来减少connect()代码。

当使用自定义控件时,如果不断添加新的小部件(如按钮,标签),会不断的新增connect代码来绑定信号和槽。这样代码会原来越多,并且在主函数中也会新增各种connect代码和自定义的信号和槽函数。为了优化代码,可以使用QSignalMapper来绑定所有的同一种部件(如按钮),这样后面增加新的小部件也不用再增加代码。

#include "toolbarwidget.h"
#include "ui_toolbarwidget.h"

#include <QFileDialog>
#include <QDebug>
#include <QSignalMapper>
ToolBarWidget::ToolBarWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ToolBarWidget)
{
    ui->setupUi(this);
    //绑定自定义的退出登录信号
    connect(ui->BtnQuit,&QPushButton::clicked,this,&ToolBarWidget::quitLogin);

    //首先创建一个mapper对象
    QSignalMapper* mapper = new QSignalMapper(this);
    //遍历所有的按钮
    QList<QPushButton*> buttonList = findChildren<QPushButton*>();
    //绑定信号和槽
    for(auto btn : buttonList)
    {
        connect(btn,SIGNAL(cilcked()),mapper,SLOT(map()));
        //检查按钮和文本,如果是绑定关系,就发出mapped信号
        mapper->setMapping(btn,btn->text());
    }
    //将信号发射出去
    connect(mapper,SIGNAL(mapped(QString)),this,SIGNAL(buttonClicked(QString)));

}

在主函数(主窗口)中,就只需绑定一次,只需创建一个统一的槽函数来对所有的小部件(比如按钮)进行信号的响应。

connect(ui->widgetToolBar,&ToolBarWidget::buttonClicked,this,&UiMain::onButtonClicked);

假如是按钮,通过匹配按钮的文本,来进行不一样的操作。 

void UiMain::onButtonClicked(const QString &text)
{
    if(text == "确定")
    {
        /* 相应代码 */
    }
    if(text == "刷新")
    {
        /* 相应代码 */
    }
}

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值