(九)QT的信号和槽介绍

在(一)QT学习中,我有提过信号和槽,并且说这个是QT的最有意思的地方,那么我们就先来看看这个机制是怎么样的吧

首先让我们新建一个项目,来看下信号和槽的用法。信号和槽是分开的,信号就是signal,槽是slot,在QT4中你可以非常直观的看到哪个是信号,哪个是槽,因为QT4是这样写的:
先定义下信号(不需要指定类型,默认就是public):

signals:
    void signal_send_test();

再定义下槽(槽必须指定类型,可以是public protect private,一般常用public,因为方便其他类connect访问到):

public slots:
    int slot_get_test();

QT4的connect:

connect(this,SIGNAL(signal_send_test()),this,SLOT(slot_get_test()));

connect(发送者,信号,接受者,槽),很简单,发送者就是谁发送信号,接受者就是谁接受并响应槽函数。我上面说非常直观就是因为SIGNAL和SLOT这两个宏,清晰的告诉你哪个是信号哪个是槽。
但是这种方式被QT5抛弃了(虽然QT5因为兼容问题,你还可以这样写,但是QT非常不推荐)。为啥呢?你可以看下SIGNAL和SLOT的定义,其实connect也可以看到:

bool connect(const QObject *, const char *,  
             const QObject *, const char *,  
             Qt::ConnectionType); 

看到了么,信号和槽都是const char*,说明对connect函数来说,信号和槽就是两个字符类型,也就是SIGNAL和SLOT的作用就是把你传入的函数名转成字符类型。
既然你是字符类型,编译器编译阶段啥也检测不到啊!!!!!!,你把槽函数和信号名写成花都没问题:

connect(this,SIGNAL(signal_send_test()),this,SLOT(slot_get()));

编译器根本检测不出来好么,对它来说这就是一堆意义不明的字符,和你定义的啥string xxxx没啥区别。你把信号名写错没啥,最多你点击没啥响应,不会发生任何事。但是你敢把槽函数名写错试试,运行以后分分钟崩溃给你看!
(网上一堆文章解释原理,但是我还是忍不住。。。初学者特别容易犯,你复制粘贴函数名不好么,自己敲啥呢!!特别是你代码量一多,代码走读,十个人都看不出来你少个t。。。)

吐槽完QT4,我们来看下QT5推荐的写法:

connect(this,&MainWindow::signal_send_test,this,&MainWindow::slot_get_test);

这个就很灵性了,他要求传入的是函数指针,也就是指向函数对象的指针。既然是指针,你函数名给我错一个试试!!!
在QT的定义中是这样写的,我觉得可以帮助你理解:

    static QMetaObject::Connection connect(const QObject *sender, const QMetaMethod &signal,
                        const QObject *receiver, const QMetaMethod &method,
                        Qt::ConnectionType type = Qt::AutoConnection);

所以总结下信号和槽的用法:
1.定义信号和槽:

signals:
    void signal_send_test();
public slots:
    int slot_get_test();

2.建立连接函数(.cpp文件中,需要的时候建立,或者直接在构造函数中建立):

connect(this,&MainWindow::signal_send_test,this,&MainWindow::slot_get_test);

3.发送信号:

emit signal_send_test();

然后下面你就不用管了,QT的元对象系统就好了,你专注你的槽函数就行

那让我们尝试下:
拖个button和label过来,点击button,让label显示文字
在这里插入图片描述

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    connect(this,&MainWindow::signal_send_test,this,&MainWindow::slot_get_test);
}

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

int MainWindow::slot_get_test()
{
    ui->label->setText(QString("hello, i'm QT"));
    return 0;
}

void MainWindow::on_pushButton_clicked()
{
    emit signal_send_test();
}

点击下按钮,就变成这样:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值