文章目录
在Qt中,允许自定义信号和槽函数。
其中自定义槽函数是非常频繁的,但是自定义信号函数频率较低,这是由于Qt中内置的信号几乎可以覆盖到用户的操作,简单来说就是用户的操作是可以穷举的。尽管如此,学习自定义的信号函数也是有必要的。
在下面的文章,我们会先讲解更重要的自定义槽函数再去讲解自定义信号。
1. 自定义槽函数
1.1 基础语法
- 在早期的Qt版本要求槽函数必须写到
public solts
下,但是在现在的高版本的Qt(Qt5及以上)允许写到类public
作用域或者全局下。 - 返回值为
void
,需要声明,也需要实现。 - 可以到参数,可以重载。
绑定自定义的槽函数有两种方法:
- 通过
connect
函数连接信号。 - 通过函数名字的方式来自动连接。
下面会详细的演示这两种方法。
1.2 使用connect
连接信号
这种方式在之前的文章就已经有所涉及了。
关于connect
函数的介绍可以看这篇文章【Qt-信号与槽】connect函数的用法-CSDN博客
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
button = new QPushButton(this);
button->setText("我是一个按钮~");
button->move(100,100); // 移动位置到(100,100)像素
connect(button,&QPushButton::clicked,this,&Widget::handle);
}
Widget::~Widget()
{
delete ui;
}
void Widget::handle()
{
button->setText("被点击了~");
}
头文件:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPushButton>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
public slots://可以不写
void handle();
private:
Ui::Widget *ui;
QPushButton* button;
};
#endif // WIDGET_H
运行效果:
1.3 使用函数名字的方式来自动连接
双击fromfile中的ui文件
进入图形化构建的界面。
拖动PushButton
控件到中间的界面,右键控件点击转到槽。
然后再点击箭头所☞的内容。
点吉ok后,回到主界面,可以看到这样的界面
这个就是系统自动生成的槽函数,有个这个槽函数我们就不要在显示的写connect
函数,下面看演示:
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
ui->pushButton->setText("被点击了~");
}
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_pushButton_clicked();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
有人有疑问吗?为什么不用connect
就可以关联信号的槽?
其实也不是没有,只是Qt也自动生成了,而且还有格式要求,打开widget.ui
文件,
不知道怎么打开的话看这篇文章:【Qt】初始项目代码解释-CSDN博客的目录5
widget.ui
:
在这个自动生成的文件中,可以看到一个类似于connect
的函数。Qt在调用自动生成的槽函数时就会调用这个函数。
所有这自动生成的槽函数的名字也是有严格的要求的,一下是要求:
命名规则on_xxx_sss
- 以
on
开头,中间使用下滑线连接起来。 xxx
表示的是对象名,控件的objectName属性。SSS
表示的对应的信号
注意:
如果我们通过图形化界面场景控件的话,就推荐这种快速的方式连接函数和槽。
如果我们是通过代码的方式创建的控件,还是推荐手动的写connect
.(你的代码中也没有connectSlotByName
)
2.自定义信号函数
基础语法
- 自定义信号函数必须写到
signals
下。 - 返回值为
void
,只需要声明,不需要实现。 - 可以有参数,也可以发生重载。
自定义信号函数的本质也就是一个特殊函数而已,这是真的,下面我们会开始演示。
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
connect(this,&Widget::mySignal,this,&Widget::handle);
//emit mySignal();
}
Widget::~Widget()
{
delete ui;
}
void Widget::handle()
{
this->setWindowTitle("自定义信号喵~");
}
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
signals:
void mySignal();
public slots:
void handle();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
运行后发现什么变化都没有呢,这是因为我们没有调用啊。
我们把注释放开
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
connect(this,&Widget::mySignal,this,&Widget::handle);
emit mySignal();
}
Widget::~Widget()
{
delete ui;
}
void Widget::handle()
{
this->setWindowTitle("自定义信号喵~");
}
这样就成功发出信号了,这个信号是不是就相当于函数,调用这个信号就是发出信号。
再修改修改代码
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
connect(this,&Widget::mySignal,this,&Widget::handle);
}
Widget::~Widget()
{
delete ui;
}
void Widget::handle()
{
this->setWindowTitle("自定义信号喵~");
}
void Widget::on_pushButton_clicked()
{
emit mySignal();
}
3.知识补充
3.1 signals和slots
无论是signals
还是slots
都是Qt字节扩展出来的关键字,不是C+标准中的语法。
除此之外Qt里还大量的使用了元编程的技术(根据代码生成代码)
qmake在构建Qt项目的时候,就会调用专门的扫描器,扫描代码中的关键字,基于关键字自动生成一大堆相关的代码。
3.2 emit
emit也就是发射的意思,作用是发出信号,emit是一个空的宏,emit是可选的,不加也不会影响自定义信号函数的发生。
即便如此,在实际的开发中,还是建议大家,把emit加上,这样的话可读性会变高~
4. 总结
在Qt中,允许自定义信号和槽函数。
自定义槽函数在实际的开发中使用是非常频繁的,不可能不学,自定义信号函数尽管在实际的开发中使用不多,但是还是不得不学啊。
希望本文对你理解自定义信号和槽函数有帮助~
往期文章:
【Qt】初始项目代码解释-CSDN博客
【Qt】HelloWorld程序-CSDN博客
【Qt-信号与槽】connect函数的用法-CSDN博客