【QT(三)】—— 信号和槽

前言

简单了解了Qt,现在来学习Qt中的 信号和槽

信号和槽

在 Qt 当中,用户和控件的每一次交互过程称为一个事件;例如:用户点击按钮、用户关闭窗口。这些事件都会发出一个信号

Qt中所有的控件都具有接受信号的能力,并且一个控件还可以接受多个不同的信号。对于接收到的每个信号,控件就会做出相应的动作。

对于接受到的信号,所做出的相应动作,就是 (槽函数)

在Qt中,事件 是用户与控件的交互行为(如点击按钮、输入文本),而控件在事件发生后会发出信号 是响应信号的函数------信号是"通知",槽是"动作",二者通过connect绑定,实现"事件触发→信号发送→槽函数执行"的逻辑链。

信号和槽,是Qt特有的消息传输机制,能将相互独立的控件关联起来。

例如:点击按钮,没有任何反应;就可以对cdicked信号,设置对应的槽函数,这样在点击时就会做出相对应的动作。

connect 的使用

在之前,我们只是创建出来一个控件(文本、按钮等),实际运行起来,点击按钮是没有任何反应的。

那是因为我们并没有对该控件产生的信号关联槽函数,也就是没有对该控件产生的信号做处理。

要将控件产生的信号关联槽函数就要使用connect

对于connect函数,包含4个需要传递的参数:

  • sender:表示产生信号的控件(谁产生的信号)
  • signal:表示产生的什么信号(产生的什么信号)
  • receiver:表示信号的接受方(谁处理这个信号)
  • method:表示信号的处理方法(如何处理这个信号)

这里创建一个按钮,对该按钮产生的clicked信号(按下)关联槽函数(Widget::close)关闭窗口

cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    QPushButton* button = new QPushButton(this);
    button->move(200,200);
    connect(button,&QPushButton::clicked,this,&Widget::close);
}

这样,在按下按钮时,整个程序窗口就会被关闭。

自定义槽函数

上述关联的槽函数是Widget::close,是Qt内置的槽函数;

当然,我们也可以自己实现一个槽函数,并于某个控件产生的信号关联。

例如,这里自定义一个槽函数,实现按下按钮,使得按钮上的文字在hello qthello world直接切换

cpp 复制代码
//在Widget.h在声明
class Widget : public QWidget
{
    Q_OBJECT
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
public slots:
    void handle();
private:
    Ui::Widget *ui;
};
//在Widget.cpp中定义
void Widget::handle()
{
    if(ui->pushButton->text() == "hello qt")
            ui->pushButton->setText("hello world");
    else
        ui->pushButton->setText("hello qt");
}
//在Widget构造函数中关联槽函数
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    connect(ui->pushButton,&QPushButton::clicked,this,&Widget::handle);
}

这样,就对于创建的按钮产生的clicked信号关联了自定义槽函数。

无论是使用代码创建QPushButto对象,还是通过form图形化界面创建的按钮都可以使用connect关联槽函数。

自定义槽函数 ,需要在声明时带上public slots字段。(Qt 5以后版本也可以不用带该字段)

自定义信号

在Qt当中,内置了非常多的信号和槽函数,这样内置的信号槽可以满足大部分的开发需求。

我们也可以自定义信号,并且对于自定义的信号关联槽函数。

自定义信号,需要带上signals:字段(Qt 5 以后版本可以不用带该字段)

自定义信号只需声明,无需定义

cpp 复制代码
//Widget.h
class Widget : public QWidget
{
    Q_OBJECT
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
signals:
    void mysignal();
private:
    Ui::Widget *ui;
};

自定义信号,也可以关联槽函数(内置和自定义槽函数都可以)

cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    connect(this,&Widget::mysignal,this,&Widget::close);
}

到这里,我们会发现:自定义了信号,关联了槽函数;

但是没有触发信号啊,运行起来没有任何反应啊

触发信号

对于内置信号,例如clicked,用户按下按钮就会触发;

而自定义信号,用户操作不会触发我们自定义的信号,就需要我们手动触发。

触发信号的关键字emit(Qt 5 以后版本也可以省略该字段)

cpp 复制代码
emit mysignal();

到这里,我们会发现:所谓的信号和槽,不就是类中的不同函数吗。

参数问题

对于自定义信号和槽,可以给其设定参数。

对于带参数的信号,在关联槽函数时就要注意:

  • 参数类型必须相同。
  • 参数个数可以不同,信号的参数个数必须大于或等于槽函数的参数个数。

form自动生成槽函数

我们可以使用form创建控件,当然也可以使用form来生成对应的槽函数。

这样就可以自动生成对应槽函数的声明和定义

通过这种方式创建的槽函数是不需要调用connect关联的

这种方式生成的槽函数,命名是有规律的:on_objectName_signal

objectName:创建控件时,控件属性objectName对应的值

signal:所关联的信号名称

disconnect取消关联

connect可以关联槽函数,而distconnect就取消信号和槽函数的关联。

disconnect的用法和connect一样,需要传递4个参数。

其常用在取消关联某一个槽函数,转而关联另外一个槽函数。

lambda 简化槽函数

C++11中,存在lambda表达式,这里在调用connect,传递槽函数时,就可以使用lambda来充当槽函数。

对于Qt 5 以后的版本,默认按照 C++ 11来进行编译的;而对于旧版本,就需要在.pro文件中加上C++11的编译选项。

相关推荐
Emily156853598702 分钟前
Emerson 1C31129G03 Analog Input Module
java·开发语言·前端·plc·emerson·1c31129g03·input module
就叫_这个吧5 小时前
Java递归方法实现面包屑导航
java·开发语言
fīɡЙtīиɡ ℡5 小时前
AI 应用系统设计
java·开发语言·人工智能
今天AI了吗7 小时前
Python 基础语法(一):常量、变量、输入输出与运算符
开发语言·数据库·人工智能·python·sql·深度学习·机器学习
TELL5217 小时前
selenium webdriver 第二次初始化的异常
开发语言·python
动词ing8 小时前
【C语言】自定义函数+指针入门
c语言·开发语言·算法
重生之后端学习8 小时前
283. 移动零[简单]✅
开发语言·数据结构·算法·leetcode·职场和发展
动词ing9 小时前
【C语言】结构体+文件基础
c语言·开发语言·数据结构
caimouse9 小时前
ReactOS 窗口系统分析(7):分层窗口与绘制辅助 — layered.c + draw.c
c语言·开发语言
丰锋ff9 小时前
基于 Qt 的智慧社区物业管理系统
开发语言·qt