【Qt】7.信号和槽_connect函数用法(2)

文章目录

  • [3. 信号和槽的使用](#3. 信号和槽的使用)
    • [3.2 查看内置信号和槽](#3.2 查看内置信号和槽)
    • [3.3 通过 Qt Creator 生成信号槽代码](#3.3 通过 Qt Creator 生成信号槽代码)
    • [3.4 第二种创建槽函数的方式](#3.4 第二种创建槽函数的方式)

3. 信号和槽的使用

3.2 查看内置信号和槽

两个问题:

咋知道的QPushButton有个clicked信号?

咋知道的QWidget有一个close槽?

Qt里到底都提供了哪些内置的信号和槽可以让我们直接使用呢?

大家在翻阅文档的时候,如果在当前类中没有找到对应的线索,不妨看看这个类的父类。
系统自带的信号和槽通常是通过 "Qt 帮助文档" 来查询。

如上述示例,要查询 "按钮" 的信号,在帮助文档中输入:QPushButton

  • 首先可以在 "Contents" 中寻找关键字 signals
  • 如果没有找到, 继续去父类中查找. 因此我们去他的父类 QAbstractButton 中继续查找关键字 signals

这里的 clicked() 就是要找的信号。这里的参数checked暂时用不到,后面遇到了再说。

槽函数的寻找方式和信号一样,只不过它的关键字是 slot


connect的具体用法:

cpp 复制代码
bool connect(const QObject *sender, 
             const char *signal_, 
             const QObject *receiver, 
             const char *method, 
             Qt::ConnectionType type = Qt::AutoConnection);

我们可以看到第2,4个参数类型都是char*

cpp 复制代码
connect(button,&QPushButton::clicked,this,&Widget::close);

但是这里的第2,4个参数类型是void(*)(),是函数指针,但是函数指针有很多种。

C++中,不允许你使用两个不同的指针类型,相互赋值,(函数传参,本质上就是赋值)

cpp 复制代码
void(*)()
bool(*)()
即使是这两个函数指针的类型都是不一致的!!

这个函数声明,是以前l日版本的Qt的connect函数的声明,以前版本中,传参的写法和现在其实也是有区别的。

此时,给信号参数传参,要搭配一个SIGNAL宏。

给槽参数传参,搭配一个SLOT宏。

SIGNAL宏和SLOT宏会将传入的函数指针转成char*

cpp 复制代码
connect(button,SIGNAL(&QPushButton::clicked),this,SLOT(&Widget::close);

Qt5开始,对上述写法做出了简化。不再需要写SIGNAL和SLOT宏了。

connect提供了重载版本,重载版本中,第二个参数和第四个参数成了泛型参数,允许咱们传入任意类型的函数指针了。

也就是CPP泛型编程

此时connect函数就带有了一定的参数检查功能。

如果你传入的第一个参数和第二个参数不匹配,或者第三个参数和第四个参数不匹配(不匹配指的是:2,4参数的函数指针,不是1,3参数的成员函数)

此时代码编译出错。


3.3 通过 Qt Creator 生成信号槽代码

Widget.h

cpp 复制代码
#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();

    void handleClicked();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

Widget.cpp

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>

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

    QPushButton* button = new QPushButton(this);
    button->setText("按钮");
    button->move(100,100);

    connect(button,&QPushButton::clicked,this,&Widget::handleClicked);
}

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

void Widget::handleClicked()
{
    //按下按钮,修改窗口标题
    this->setWindowTitle("按钮已经按下");
}

运行:

点击


3.4 第二种创建槽函数的方式

先新建项目,点击.ui控件

Push Button按钮拖到页面

右键按钮,点击转到槽

这个窗口就列出了QPushButton给我们提供的所有的信号(还包含了QPushButton父类的信号)

对于普通按钮来说, 使用 clicked 信号即可。 clicked(bool) 没有意义的,具有特殊状态的按钮(比如复选按钮)才会用到 clicked(bool)

双击clicked,就会自动生成一个函数并跳转,并且声明也有

运行,点击

可以发现这里没有connect,并且在对应的ui_widget文件里面也没有。

Qt中,除了通过connect来连接信号槽之外,还可以通过函数名字的方式来自动连接。

说明:

自动生成槽函数的名称有一定的规则。槽函数的命名规则为:on_XXX_SSS,其中:

  1. 以 " on " 开头,中间使用下划线连接起来;

  2. " XXX " 表示的是对象名(控件的 objectName 属性)。

  3. " SSS " 表示的是对应的信号。

如:" on_pushButton_clicked() " ,pushButton 代表的是对象名,clicked 是对应的信号。
按照这种命名风格定义的槽函数,就会被 Qt 自动的和对应的信号进行连接。

但是咱们日常写代码的时候,除非是 IDE 自动生成,否则最好还是不要依赖命名规则,而是显式使用 connect 更好。

一方面显式 connect 可以更清晰直观的描述信号和槽的连接关系,另一方面也防止信号或者槽的名字拼写错误导致连接失效。

当函数名符合上述规则之后,Qt就能自动的把信号和槽给建立上联系。

如果我们把on_pushButton_clicked改成on_pushButton_click,那么运行后点击按钮无反应,没有连接槽,并且出现下面提示,因为后者不存在Qt中。

Qt中调用这个函数的时候,就会触发上述自动连接信号槽的规则

正是在自动生成的ui_widget.h中调用的。

如果我们通过图形化界面创建控件,还是推荐使用这种快速的方式来连接信号槽

如果我们是通过代码的方式来创建控件,还是得手动connect。(代码中没有调用connectSlotsByName

相关推荐
姚远Oracle ACE3 小时前
解读Oracle AWR报告:Global Cache and Enqueue Services - Workload Characteristics
数据库·oracle
凤山老林3 小时前
新一代Java应用日志可视化与监控系统开源啦
java·后端·开源
金涛03193 小时前
QT-day2,信号和槽
开发语言·qt·命令模式
Zzz 小生5 小时前
Claude Code学习笔记(四)-助你快速搭建首个Python项目
大数据·数据库·elasticsearch
黎宇幻生7 小时前
Java全栈学习笔记39
java·笔记·学习
Aurorar0rua7 小时前
C Primer Plus Notes 09
java·c语言·算法
nongcunqq8 小时前
abap 操作 excel
java·数据库·excel
rain bye bye9 小时前
calibre LVS 跑不起来 就将setup 的LVS Option connect下的 connect all nets by name 打开。
服务器·数据库·lvs
史迪奇_xxx9 小时前
10、一个简易 vector:C++ 模板与 STL
java·开发语言·c++