首页 > 编程学习 > 《Qt5:信号和槽使用示例》

《Qt5:信号和槽使用示例》

发布时间:2022/5/14 15:49:53

信号和槽介绍 


信号和槽用于对象之间的通信。信号和槽机制是Qt的核心功能,是与其他框架提供的功能最不同的部分。

在GUI编程中,当更改了某个窗口部件的状态时,需要通知另外一个窗口部件做出相应的操作。例如,如果点击了“关闭按钮,软件需要调用close()函数来关闭当前窗口。

其它开发工具可能使用回调实现这种通信,回调是指向函数的指针,因此如果希望处理函数通知您某些事件,则将指针传递给处理函数的另一个函数(回调),然后处理函数在适当时调用回调。但回调不直观,并且在确保回调参数的类型正确性方面存在问题。

我们通常使用的是信号和槽是一一对应的,其实也可以一对多。

信号

Qt内部自带了各种窗口部件的信号,最常见的就是按钮的clicked()。但是也可以自己声明信号,声明信号需要使用signals关键字,在signals前面不能用public、private和protected等限定符,信号默认是public函数,可以从任何地方进行发射。

: 

槽就是普通的C++函数,可以像一般的函数一样使用。声明槽函数要使用slots关键字,可以是private、public或者protected类型的,槽也可以被声明为虚函数。它最大的特点就是可以和信号关联,这是其它函数比不了的。

信号和槽使用注意事项

1、需要继承自QObject或其子类;

2、 使用信号和槽必须在类声明的最开始处添加Q_OBJECT宏;

3、槽中参数类型要和信号参数的类型相对应,且不能比信号的参数多;

4、信号只有声明,没有定义,且返回值为void类型;

5、槽有声明,也有定义。

信号和槽的关联

信号和槽关联使用的是QObject类的connect()函数,需要注意的是,connect()函数中信号和槽的参数只能为类型,不能有变量名。

Qt5版本函数原型

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

第一个参数:发射信号的对象

第二个参数:发射的信号

第三个参数:接受信号的对象

第四个参数:要执行的槽

第五个参数:信号和槽的关联方式,默认为自动关联

 Qt5版本使用示例

connect(ui->pushButton,&QPushButton::clicked,this,&MainWindow::closeWindow);

Qt4版本函数原型

static QMetaObject::Connection connect(const QObject *sender, const char *signal,
                        const QObject *receiver, const char *member, Qt::ConnectionType = Qt::AutoConnection);

 Qt4版本使用示例

connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(closeWindow()));

两个版本的区别

Qt4的SIGNAL和SLOT两个宏实际上是将其参数转换为相应的字符串。在编译之前,Qt的moc工具从源代码中提取出所需的元数据,形成一张由使用了signals和slots修饰的所有函数组成的字符串表。connect函数将与信号关联起来的槽的字符串,同这张字符串表中的信息比较,从而知道在发出信号时知道需要调用哪个槽函数。

这种信号和槽的语法造成了两个问题:

1、没有编译器检查;

2、无法使用相容类型的参数。

为了解决这两个问题,Qt5对信号和槽的语法进行了改进。发送信号的类型是Sender,接受信号的类型是Receiver。改进后的优点如下所示:

1、支持编译期检查。信号和槽的拼写检查、参数匹配检查。

2、支持相容类型参数的自动转换。支持使用typedef或者命名空间,还支持使用隐式类型转换。

3、允许连接到任意函数。

尽管新版本有所改进,但是Qt4的语法还是可以用在Qt5的代码中的。

 

信号和槽使用示例


1、打开Qt Creator开发工具,新建一个Qt Widgets Application项目,在主窗口上添加一个pushButton按钮。

2、添加Q_OBJECT宏:使用信号和槽必须在类声明的最开始处添加Q_OBJECT宏,一般自己生成。

Q_OBJECT

3、声明槽函数:和声明普通的成员函数差不多,只不过多了一个slots关键字

private slots:
    void closeWindow();

4、在mainwindow.cpp中添加如下代码,实现的功能是点击一下“关闭窗口”按钮,就调用槽,关闭主窗口,相当于执行了窗口右上角那个红叉的操作。

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

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setWindowTitle(tr("信号和槽"));
    ui->pushButton->setText(tr("关闭窗口"));
    //Qt5
    connect(ui->pushButton,&QPushButton::clicked,this,&MainWindow::closeWindow);
    //Qt4
    //connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(closeWindow()));
}

//关闭窗口
void MainWindow::closeWindow()
{
    close();
}

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

效果图

还可以通过Qt Designer添加信号槽,选中按钮点击鼠标右键,选择“转到槽”,进入“转到槽”页面,选择一个信号,系统会自动生成相应的槽函数on_pushButton_cliceked(),由字符串on、部件的对象名和信号名称三部分组成,因此如果用户自定义槽,就不允许使用此种命名方式,以免冲突,此种方法添加信号槽不需要使用关联函数。

Copyright © 2010-2022 ngui.cc 版权所有 |关于我们| 联系方式| 豫B2-20100000