【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的编译选项。

相关推荐
盼哥PyAI实验室2 小时前
Python自定义HTTP客户端:12306抢票项目的网络请求管理
开发语言·python·http
这儿有一堆花2 小时前
Python优化内存占用的技巧
开发语言·python
NaturalHarmonia2 小时前
【Go】sync package官方示例代码学习
开发语言·学习·golang
遥望九龙湖2 小时前
3.析构函数
开发语言·c++
gihigo19982 小时前
MATLAB中进行综合孔径微波辐射成像仿真
开发语言·matlab
Three K3 小时前
Redisson限流器特点
java·开发语言
Halo_tjn3 小时前
Java 多线程机制
java·开发语言·windows·计算机
mengzhi啊3 小时前
qt自制文本,应该没什么用
qt
Jeff-Nolan3 小时前
C++运算符重载
java·开发语言·c++