Qt 具备让某个对象的信号与符合要求的槽函数自动建立连接。弄起来也很简单,只要调用这个静态方法即可:

QMetaObject::connectSlotsByName(...);

connectSlotsByName 方法需要一个参数,此参数的指针指向一个实例,这个实例自身的信号,以及它的子级对象的信号都会自动连接。

不过,在用的时候要注意以下几点,否则 connectSlotsByName 方法是不起作用的。

1、如果类是从某个 QObject 类派生的,比如常见的 QWidget 类,在类的声明中一个定要加上 Q_OBJECT 宏。这条老周在上一篇中说过,不加这个信号和槽不能建立连接。

2、对象一定要有 Name,即用 setObjectName 方法设置。虽然对象可以使用重复的名字,但不建议这样做,因为 connectSlotsByName 方法只要找到一个名字匹配的对象,就会停止查找。所以,就算你设置了 10 个名为“myButton” 的对象,结果也只能有一个会自动绑定信号和槽,其他的同名对象会忽略。

3、一定要在所有对象都初始化完毕,包括调用 setObjectName 方法设置对象名称后调用 connectSlotsByName 方法。这样才会有效。

setObjectName 方法用起来很简单,只要传递对象的名字即可,字符串类型。名字你可以随便取。例如

QLabel lb ...
lb.setObjectName("bug");

这时候,标签对象的名字是“bug”。

Slot 要支持被自动连接,函数(方法)也是有严格的命名规则的。你必须按照这个规则来,否则不会被识别。槽函数命名规则如下:

on_XXX_SSS

1、以“on”开头,每一节用下划线连起来。

2、XXX 是对象名,注意是对象名,就是用 setObjectName 方法设置的名称,不是你代码中定义的变量名。这个得注意,不能搞错了。

3、SSS 是信号。

比如,按钮的 clicked 信号,你让要自己写的槽能够被自动连接,就得这样命名槽函数:on_mybtn_clicked。其中,“mybtn”是对象名。

------------------------------------------- 银河分隔线 ------------------------------------------

下面咱们来动手做个例子,就好理解了。

一、先弄好 CMake 文件。

cmake_minimum_required(VERSION 3.0.0)
project(TestApp VERSION 0.1.0) find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_AUTOMOC YES) add_executable(TestApp WIN32 main.cpp app.h app.cpp)
target_link_libraries(TestApp PRIVATE Qt6::Core Qt6::Gui Qt6::Widgets)

这个示例有三个文件。main.cpp 是写 main 函数的地方。app.h 和 app.cpp 中是咱们自定义的窗口类——从 QWidget 类派生。

二、定义 MyWindow 类,基类是 QWidget。

/** app.h **/
#include <QMetaObject>
#include <QWidget>
#include <QApplication>
#include <QObject>
#include <QLabel>
#include <QPushButton>
#include <QMessageBox>
#include <QVBoxLayout>
#include <QHBoxLayout> class MyWindow : public QWidget
{
// 这个宏很容易忘了,忘了就不能连接信号和槽了
Q_OBJECT public:
// 构造函数
MyWindow(QWidget* parent = nullptr);
// 析构函数
~MyWindow(); private:
// 私有函数
void initUi(void);
// 以下是用到的部件(控件)
QPushButton *btn1;
QPushButton *btn2;
QLabel *lb;
// 布局
QVBoxLayout *layout;
QHBoxLayout *sublayout; // 这几个函数是用于自动绑定的槽
private slots:
void on_b1_clicked();
void on_b2_clicked();
};

所有 QObject 的子类,想使用 Signal 和 Slot ,必须调用 Q_OBJECT 宏。这里有两个按钮,on_b1_clicked 和 on_b2_clicked 都是槽。要让两个按钮自动连接,必须分别设置它的 object name 为 “b1” 和 “b2”。

三、下面是 initUi 函数的实现代码,用于初始化窗体。

void MyWindow::initUi()
{
// 按钮1
btn1 = new QPushButton(this);
// 设置按钮1的文本
btn1 -> setText("左边");
// 重要:给它个名字
btn1 -> setObjectName("b1"); // 按钮2
btn2 = new QPushButton(this);
// 设置按钮2的文本
btn2 -> setText("右边");
// 重要:设置名称
btn2 -> setObjectName("b2"); // 标签
lb = new QLabel("请点击下面的按钮", this); // 布局
layout = new QVBoxLayout(this);
layout -> addWidget(lb, 0, Qt::AlignTop);
sublayout = new QHBoxLayout(this);
// 添加要布局的组件
sublayout -> addWidget(btn1);
sublayout -> addWidget(btn2);
layout->addLayout(sublayout); // 窗口
this -> setWindowTitle("示例王");
this -> resize(240, 100);
}

调用按钮对象的 setObjectName 方法就可以为其分配名称。注意在调用 QPushButton 类的构造函数时,要把当前窗口的指针传递给 parent 参数,使用按钮成为 MyWindow 的子级对象。这样后面才能做信号与槽的自动连接。

四、在 MyWindow 类构造函数中,先调用 initUi ,再调用 connectSlotsByName 静态方法。

MyWindow::MyWindow(QWidget *parent)
: QWidget::QWidget(parent)
{
// 调用以下函数,初始化UI
initUi();
// 一定要在所有东东都初始化完毕后调用才有效
QMetaObject::connectSlotsByName(this);
}

五、下面是两个槽函数的实现。功能简单,用 QMessageBox 显示弹出框。

void MyWindow::on_b1_clicked()
{
QMessageBox::information(this, "好消息", "左转是男厕", QMessageBox::Ok);
}
void MyWindow::on_b2_clicked()
{
QMessageBox::information(this, "好消息", "右转是女厕", QMessageBox::Ok);
}

六、在 main.cpp 中写 main 函数。

#include "app.h"

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// 实例化窗口
MyWindow wind;
// 显示窗口
wind.show();
// 消息循环
return app.exec();
}

运行结果如下面超清动画所示。

从结果可以看到,名为“b1”的按钮自动将 clicked 信号连接到 on_b1_clicked 函数;名为“b2”的按钮自动将 clicked 信号连接到 on_b2_clicked 函数。

好了,今天的主题咱们就聊到这儿了。

用 VS Code 搞 Qt6:让信号和槽自动建立连接的更多相关文章

  1. 用 VS Code 搞 Qt6:信号、槽,以及QObject

    Qt 里面的信号(Signal)和槽(Slot)虽然看着像事件,但它实际上是用来在两个对象之间进行通信的.既然是通信,就会有发送者和接收者. 1.信号是发送者,触发时通过特有的关键字"emi ...

  2. Qt5 UI信号、槽自动连接的控件重名

    Qt5 UI信号.槽自动连接的控件重名 来源 http://blog.csdn.net/goldenhawking/article/details/51865909 对Qt5稍有熟悉的童鞋都知道信号. ...

  3. 用VS Code搞Qt6:编译源代码与基本配置

    先说明一下,本水文老周仅讨论新版的 Qt 6,旧版的 Qt 不讨论. 尽管 Qt 有自己的开发环境,但老周必须说句不装逼的话:真的不好用.说起写代码,当然了,用记事本也能写.但是,有个高逼格的工具,写 ...

  4. 用 VS Code 搞Qt6:使用 PySide 6

    一般来说,用C++写 Qt 应用才是正宗的,不过,为了让小学生也能体验 Qt 的开发过程,或者官方为了增加开发者人数,推出了可用 Python 来编程的 Qt 版本.此版本命名比较奇葩,叫 PySid ...

  5. Qt5 UI信号、槽自动连接的控件重名大坑(UI生成的槽函数存在一个隐患,即控件重名。对很复杂的控件,不要在 designer 里做提升,而是等到程序启动后,再动态创建,可以避免很多问题)

    对Qt5稍有熟悉的童鞋都知道信号.槽的自动连接机制.该机制使得qt designer 设计的UI中包含的控件,可以不通过显式connect,直接和cpp中的相应槽相关联.该机制的详细文章见 http: ...

  6. Qt信号与槽自动关联机制

    参考链接1:http://blog.csdn.net/skyhawk452/article/details/6121407 参考链接2:http://blog.csdn.net/memory_exce ...

  7. 用VS Code搞Qt6:至简窗口部件——QWidget

    在正题开始之前,老周照例扯点别的.嗯,咱们扯一下在 VS 2022 下结合 CMake 开发 Qt6 时的环境变量设置问题.在VS Code 中,通够通过 CMake Tools 扩展的配置来设置环境 ...

  8. 用VS Code搞Qt6:编译附加模块

    上一次水文中,老周所介绍的是编译 Qt 的基础模块-- qtbase.一次性编译所有代码可以一劳永逸,但体积相当大,编译时间较长,CPU负载大发热大,风扇转得猛,电费交得多.因此老周更喜欢分开来编译. ...

  9. Qt Quick 事件处理之信号与槽

    前面两篇文章<QML 语言基础>和<Qt Quick 简单教程>中我们介绍了 QML 语言的基本的语法和 Qt Quick 的常见元素,亲们,通过这两篇文章,您应该已经能够完毕 ...

随机推荐

  1. 万物皆可集成系列:低代码释放用友U8+深度价值(2)—数据拓展应用

    在上一篇内容我们介绍了如何利用低代码开发套件实现低代码应用与U8+系统的对接集成,本次给大家带来的是如何将用友U8+系统中的数据进行价值扩展和实际应用. 我们以生产物料齐套分析为例来说明如何利用低代码 ...

  2. wallpaperPKG文件提取

    简单粗暴 下载这个ZIP文件链接: 下载地址戳我 提取码: ag43 解压后双击打开如下文件 我们在解压一下repkg-master.zip解压后如下,注意我的路径进入到这些很多文件的页面 返回首页复 ...

  3. [Golang] cgo 调用 .so 捕获异常问题

    最近需要在 go 中去调用 .so 库去完成一些事情,go 方面,利用 cgo 可以顺利的调用 .so 中的方法,但是有个问题是 go 没法捕获 .so 那边出现的异常.如果 .so 那边异常了,那么 ...

  4. 搭建eBackup对接NFS服务

    环境准备 两个虚拟机需要是仅主机并且同一网段 先搭建一个eBackup环境虚拟机 搭建步骤可访问:(https://www.cnblogs.com/zhengyan6/p/16220774.html) ...

  5. React Native入门 Enable live Reload

    在开发项目时,有时一点点小修改就需要重新编译,打包,安装,效率比较低 RN 提供了一种实时重载 (Enable live Reload)的方式,来实现快速的调试开发,修改保存后会立刻载真机或模拟器中显 ...

  6. 手把手教你用Java获取IP归属地

    前几个月微信公众号上线了IP归属地的功能,后续知乎.抖音等平台纷纷添加了该功能.如果是国内的用户精确到省份,国外用户精确到国家.本文就使用Java实现获取IP归属地. ! 主要讲解几个步骤: Java ...

  7. 邮箱的代理发送Send as权限不生效

     邮箱的代理发送Sendas权限不生效 最近,有需求为用户添加其它邮箱的代理发送Sendas权限.在Exchange的管理单元里添加完毕后,发现没有效果,客户端提示你没有权限以用户的名义发送邮件 ...

  8. Elasticsearch:Smart Chinese Analysis plugin

    Smart Chinese Analysis插件将Lucene的Smart Chinese分析模块集成到Elasticsearch中,用于分析中文或中英文混合文本. 支持的分析器在大型训练语料库上使用 ...

  9. nexus清理释放磁盘空间

    应用背景 自建的maven私服(或者叫私仓)nexus在使用过程中,因很多服务不断迭代更新上传jar包至nexus中,底层存放在一个叫Blob Stores的存储中,最近发现该存储已增大至好几百G,有 ...

  10. 2>&1到底是什么意思?

    java -jar snapshot.jar > snapshot.log 2>&1 & 写Java的朋友一定对上面的命令很熟悉,相信大部分人都知道>表示的是重定向, ...