Qt 信号和槽函数

2023-11-16

信号和槽是一种高级接口,应用于对象之间的通信,它是 QT 的核心特性。当某个信号被发射,就需要调用与之相绑定的槽函数。这与Windows下的消息机制类似,消息机制是基于回调函数。一个回调即是一个函数的指针,因此如果希望一个处理函数通知一些事件,可以传递一个函数(回调函数)的指针给这个处理函数。这个处理函数就会在适当的时候调用回调函数。但是回调函数有两大缺点:第一,它们不是类型安全的。我们从来不敢确定处理函数会用正确的参数来调用回调函数;第二,回调函数被强力和处理函数联系着,因为处理函数必须知道去调用哪个回调函数。

信号和槽的机制是类型安全的:一个信号的签名必须与接收槽的签名相匹配。(实际上一个槽可能有一个比它所接收到的信号的签名更短的签名因为它能够忽略额外的参数。)因为签名是一致的,所以编译器能够帮助我们发现类型不匹配。信号和槽是松散的联系在一起的:一个发射信号的类从来不知道也不关心哪个槽接收这个信号。Qt的信号和槽机制确保如果你将一个信号和一个槽连接起来,这个槽将在正确的时间被用这个信号的参数所调用。信号和槽可以带任何数量任何类型的参数。它们完全是类型安全的。

信号(Signals)

当对象改变其状态时,信号就由该对象发射 (emit) 出去,而且对象只负责发送信号,它不知道另一端是谁在接收这个信号。这样就做到了真正的信息封装,能确保对象被当作一个真正的软件组件来使用。

信号只需要在头文件中进行声明,不需要在cpp中实现。放在Qt自定义关键字signals下,在此之前一定要加上Q_OBJECT宏。

在编程中,一般使用的是控件内部定义好的信号。如:QTreeWidget类下的 Signals:

void    currentItemChanged ( QTreeWidgetItem * current, QTreeWidgetItem * previous );
void    itemActivated ( QTreeWidgetItem * item, int column );
void    itemChanged ( QTreeWidgetItem * item, int column );
void    itemClicked ( QTreeWidgetItem * item, int column );
void    itemCollapsed ( QTreeWidgetItem * item );
void    itemDoubleClicked ( QTreeWidgetItem * item, int column );
void    itemEntered ( QTreeWidgetItem * item, int column );
void    itemExpanded ( QTreeWidgetItem * item );
void    itemPressed ( QTreeWidgetItem * item, int column );
void    itemSelectionChanged ();

也可以自定义信号,并通过emit在代码中发射信号。

class sender : public QObject
{
    Q_OBJECT

    public:
        void doSend();
    signals:
        void send(int);
};
// ------------ sender.cpp -----------
#include "sender.h"
void sender :: doSend()
{
    emit send(40);
}

槽函数(Slots)

槽和普通的C++成员函数几乎是一样的(可以是虚函数,可以被重载,可以是public slots、protected slots、private slots,可以被其他C++成员函数直接调用;唯一不同的是:槽还可以和信号连接在一起,在这种情况下,信号被发射时,会自动调用这个槽。)槽不需要信号传过来的参数时,可以不要参数;但槽一旦要参数,其参数个数,类型,顺序必须要和对应的信号保持一致。另外,槽的参数不能有缺省值。

class receiver : public QObject
{
    Q_OBJECT
 
    public slots:
        //带有参数的槽函数,需和绑定的信号的参数保持一致
        void recv(int);
};
// ------------ Receiver.cpp -----------
void receiver :: recv(int n)
{
    qDebug()<<"recv number: "<<n<<endl;
}

关联信号和槽(connect)

可以使用QObject类的静态成员函数connect来建立信号的槽的关联

bool QObject::connect (const QObject * sender, const char * signal, const QObject * receiver, const char * slot) [static]

具体的调用为:connect(sender, SIGNAL(signal), receiver, SLOT(slot)); 其中sender和receiver为QObject类对象的指针; SIGNAL宏和SLOT宏将信号的槽转换成字符串。

sender s;
receiver r;
QObject::connect(&s, SIGNAL(send(int)), &r, SLOT(recv(int)));

注:在connect函数中信号函数和槽函数若有参数,只能写出参数类型,而不能也将变量名写出;否则,连接会失败!

  • 一个信号可以连接多个槽

当信号发射时,会以不确定的顺序一个接一个的调用各个槽。

  • 多个信号可以连接同一个槽

即无论是哪一个信号被发射,都会调用这个槽。

  • 信号直接可以相互连接

发射第一个信号时,也会发射第二个信号。

断开信号和槽(disconnect)

当信号和槽没有必要继续保持连接时,可以通过调用disconnect来断开它们。

bool QObject::disconnect (const QObject * sender, const char * signal,  const Object * receiver, const char * slot) [static]

有三种情况必须使用 disconnect() 函数:

(1)断开与某个对象相关联的任何对象。

disconnect(sender, 0, 0, 0) ;
//或者
sender->disconnect();

(2)断开与某个特定信号的任何关联。

disconnect(sender, SIGNAL(signal()), 0, 0);
//或者
sender->disconnect(SIGNAL(signal()));

(3)断开两个对象之间的关联。

disconnect(sender, 0, receiver, 0);
//或者
sender->disconnect(receiver);

应注意的问题

  1. 信号与槽机制与普通函数的调用一样,如果使用不当的话,在程序执行时也有可能产生死循环。因此,在定义槽函数时一定要注意避免间接形成无限循环,即在槽中再次发射所接收到的同样信号。例如 , 在前面给出的例子中如果在 mySlot() 槽函数中加上语句 emit mySignal() 即可形成死循环。
  2. 如果一个信号与多个槽相联系的话,那么,当这个信号被发射时,与之相关的槽被激活的顺序将是随机的。
  3. 宏定义不能用在 signal 和 slot 的参数中。
  4. 信号和槽的参数个数与类型必须一致。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt 信号和槽函数 的相关文章

  • 程序意外完成 - QT Creator

    我正在尝试使用 QT Creator 使用 QT 框架开发 GUI 控制台应用程序 我使用的是Windows XP 我安装了QT 4 8 3和mingw 两者均已安装 没有任何错误 然后我安装了QT Creator QT 版本 路径中的 Q
  • QDesktopServices::openUrl 在资源管理器中选择指定文件

    在大多数编码程序中 您可以右键单击该项目 然后单击 在资源管理器中显示 它会在资源管理器中显示选定项目的文件 在 Qt 中使用 QDesktopServices 如何做到这一点 或在 QT 中执行此操作的任何方式 您可以使用此方法在 Win
  • QT/QML Android App,点击通知栏时打开应用程序

    我为 Android 应用程序制作了一个 QT 当我单击平板电脑中上面看到的按钮通知栏时 但是 如果单击通知 我的应用程序将打开 聚焦 不知道 并显示黑色窗口 简单来说怎么做呢 我的代码是 package org ays operation
  • Qt中如何获取鼠标在屏幕上的位置?

    我想获取屏幕上的鼠标坐标 我怎样才能在 Qt 中做到这一点 在 Windows 上 使用 C 我正在做类似答案中建议的事情对于这个问题 https stackoverflow com q 11737665 1420197 正如文档所述 QC
  • QTcpSocket 有时不发送数据

    我有两个 QT 应用程序 一个应用程序可以被认为保存了大数据 它每秒向第二个应用程序发送大约 10 KB 的数据块 之前我尝试使用QUdpSocket来传输数据 但由于MTU限制在2 5K左右 并且需要自己分割和重新组合数据 所以我改用QT
  • 如何将图像显示为缩略图

    我有一个QTreeView显示硬盘驱动器和目录 我也有一个QListView显示图像文件如下 但我想将图像显示为缩略图 如下所示 My code mainWidget mainWidget QWidget parent QWidget pa
  • 如何获取 QTableView 的标题列表?

    我有一个QTableView我的对话框中的对象 我需要访问该表的水平标题并将它们放入QStringList object 尽管进行了大量搜索 但我在 Qt 文档中找不到如何获取此标头列表 编辑 我发现的最接近的地方是this https w
  • 如何在 QTabWidget Qt 中展开选项卡

    我有一个QTabWidget像这个 但我想展开选项卡以 填充 整个小部件宽度 如下所示 我怎样才能做到这一点 我在用Qt 5 3 2 and Qt 创建者 3 2 1 Update 我尝试使用setExpanding功能 ui gt myT
  • Qt:测量事件处理时间

    我想测量我的应用程序中的哪些事件在主线程中需要很长时间才能执行 阻塞 GUI 或者至少是否有任何事件花费的时间超过 比如说 10 毫秒 显然 我对需要很长时间的任务使用线程和并发 但有时很难在其他线程中放入的内容和可以保留在 GUI 中的内
  • 在 MacOS 终端上运行 ffmpeg [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我对 MacOS 相当陌生 我发现使用终端来获取信息并不容易ffmpeg和我在 Window 上一样正常运行 我有 ffmpeg 二进制文件ffmpe
  • Qt 插槽是否与其他代码并行运行?

    在此函数示例中 void MyClass myFunction emit MySignal1 emit MySignal2 如果我有slot1倾听MySignal1 and slot2倾听MySignal2 1 Is slot1总是会在之前
  • Qml 模块未找到 CPP 类注册与新的 QML_ELEMENT r

    我尝试使用 Qt5 15 0 和新宏 QML ELEMENT 在 QML 中注册我的自定义 CPP 类 但找不到该模块 Qt Creater 帮助文件描述了 QML ELEMENT 的步骤 我也检查了 Qt 手册 但没有幸福的结局 http
  • Qt:在多个布局中使用一个小部件

    我有一个 QTabBar 所有选项卡都应该有相同的小部件 layout1 gt addWidget w layout2 gt addWidget w 然而打电话addWidget第二次导致该小部件在第一个布局中消失 有没有办法使用一个小部件
  • Qt - 设置不可编辑的QComboBox的显示文本

    我想将 QComboBox 的文本设置为某些自定义文本 不在 QComboBox 的列表中 而不将此文本添加为 QComboBox 的项目 此行为可以在可编辑的 QComboBox 上实现QComboBox setEditText cons
  • 如何使用meta-toolchain-qt5构建Qt(带有QtWebEngine支持)?

    我正在尝试使用构建 Qtmeta toolchain qt5 但是当我通过这样做时poky glibc x86 64 meta toolchain qt5 cortexa7hf vfp vfpv4 neon toolchain 2 0 1
  • Qt 是否已经有了自己的 new 和 delete 运算符?

    我正在使用一个QGraphicsScene小部件并在其上显示一些点QGraphicsRectItem 这意味着要拨打很多电话new addItem 当出现时 并且removeItem delete摆脱未使用的点 当然 对于性能问题 我已经实
  • Qt - 获取互联网上托管的网页的源代码(HTML 代码)

    我想获取网页的源代码 HTML 例如StackOverflow的主页 这是我到目前为止编写的代码 QNetworkAccessManager manager QNetworkReply response manager get QNetwo
  • 如何将 zlib 添加到现有的 qt 安装中

    如何将 zlib 添加到 Qt 的现有安装中 我对此很陌生 所以请给我详细的描述 提前感谢您的帮助 zlib 包含在 Qt 核心库中 如果你想在 Qt 程序中使用 zlib 函数 你只需要包含 src 3rdparty zlib 中的 zl
  • 如何为 Windows 构建静态 Qt 库并将其与 Qt Creator 一起使用

    我已经下载了以下 Qt 源 http download qt nokia com qt source qt everywhere opensource src 4 7 3 zip http download qt nokia com qt
  • 是否可以在 Qt Creator 中将 Qt 样式表与升级的小部件一起使用?

    我正在尝试使用 Qt 样式表对标准小部件进行一些重大的重新设计 因此 在为不同的小部件手动完成大部分工作之后 objectName选择器 我决定以某种方式对类似的小部件进行分组 例如我有多个QFrames其作用类似于内部表单中的标题 我希望

随机推荐

  • Oracle阻塞会话源头查找-单机和RAC环境

    在写 Oracle session相关数据字典 一 这篇文章时 提到使用v session视图的树形查询可以得到Oracle锁树 这样就便于我们找出阻塞会话的源头 但是仅仅可以在单机环境中使用 今天把单机和RAC的阻塞树都整理了一下 话不多
  • kotlin高阶函数开发一个程序,统计文本中字符串出现的个数

    一 高阶函数是Kotlin的核心部分 下面来使用下高阶函数写一个程序 注意 我这里的File使用的是 与src同级的文件 你可以根据自己的需要 修改文件地址 代码实例 package net println kotlin chapter5
  • 如何完整地掌握一个机器学习模型

    如何完整地掌握一个机器学习模型 要全面地学习 掌握一个机器学习模型 可以遵循以下步骤 基础理论学习 了解该模型的背后数学原理和推导过程 包括假设 损失函数 优化方法等 学习算法实现 通过查阅论文 教程或开源代码 了解算法的具体实现过程 尝试
  • k8s的service资源类型有ClusterIP、Nodeport、ExternalName、LoadBalancer、Headless(None)

    1 ClusterIP 是什么 ClusterIP 是在所有节点内生成一个虚拟IP 为一组pod提供统一的接入点 当service存在时 它的IP地址和端口不会发生改变 客户端通过service的ip和端口建立连接 由service将连接路
  • 20221210 QT----信号和槽的使用

    信号和槽的使用 文章内容为B站 大轮明王讲Qt 的学习笔记 什么是信号 signal 以QPushButton为例 1 按下按钮时 会触发一个mousePressEvent事件 此时会发出一个pressed信号 2 松开按钮时 会触发一个m
  • 00后确实卷,公司新来的卷王,我们这帮老油条真干不过.....

    都说00后躺平了 但是有一说一 该卷的还是卷 这不 前段时间我们公司来了个00后 工作没两年 跳槽到我们公司起薪18K 都快接近我了 后来才知道人家是个卷王 从早干到晚就差搬张床到工位睡觉了 最近和他聊了一次天 原来这位小老弟家里条件不太好
  • Spring学习笔记 Spring JDBC框架

    Spring JDBC简介 先来看看一个JDBC的例子 我们可以看到为了执行一条SQL语句 我们需要创建连接 创建语句对象 然后执行SQL 然后操纵结果集获取数据 try Connection connection DriverManage
  • CGAL 最小点数约束的体素滤波

    目录 一 概述 二 代码实现 三 结果展示 一 概述 在CGAL 5 5版本中 grid simplify point set 中添加了一个新的可选命名参数min points per cell 通过在单元格中添加最小数量的点以便保留一个点
  • C++ deque底层原理

    deque底层原理 一 目的 二 底层实现 三 原理图 四 类结构 五 push back 六 pop back 一 目的 实现双端数组 二 底层实现 双向开口的连续线性空间 三 原理图 四 类结构 class deque protecte
  • nn.embedding笔记

    nn embedding介绍 embedding就是词嵌入 将一个token转化为一个向量 其通常作为nlp模型的一个层 我们通常使用的nn embedding通常分为两种情况 使用别人训练好的nn embedding 这个时候通过nn e
  • HCNA-Storage (H13-611)题库 v4.0

    Exam A QUESTION 1 以下关于华为 RAID2 0 技术 描述正确的是 多选 A 硬盘域中每个存储层的硬盘类型相同 B 硬盘的空间被划分成固定大小的块 C 用户可以为存储池 storage pool 中的每一个存储层分别设置
  • python_基础语法_find_查找字符,不存在则返回-1

    usr bin python3 str1 Runoob example wow str2 exam print str1 find str2 print str1 find str2 5 print str1 find str2 10 不存
  • android 通过usb读取 U盘

    关联 compile com github mjdev libaums 权限设置
  • 期货交易怎么做好风险控制?

    期货交易保证金机制还有期货自带杠杆的原理要求我们在期货交易过程中要更加注重风险的控制 因为杠杆机制下盈利与亏损都会被放大 不及时止损所带来的后果是很严重的 这是期货交易中的大忌 所以今天我们就来聊一聊期货交易中我们应该怎样做到风险控制 1
  • 理解容器和虚拟化技术

    容器和虚拟化 虚拟机 虚拟化技术 硬件虚拟化 虚拟机的基础架构 深层理解虚拟机 如何运行多个隔离应用 容器 容器技术 容器的作用 容器运行多个相互隔离的应用 docker为例 虚拟机和容器的区别 Docker 什么是docker docke
  • kube-apiserver 报错 Unable to authenticate the request“ err=“[x509: certificate signed by unknown ...

    问题描述 采用ansible 二进制方式部署kubernetes 部署完成后kubectl get node 节点状态 NotReady kubectl get pod n kube system 发现 calico 处于 Pending
  • linux ssh Unused,安装openssh-portable时遇到的问题及解决办法

    问题1 configure error Your OpenSSL headers do not match your library Check config log for details If you are sure your ins
  • [pytorch]关于cross_entropy函数

    loss F cross entropy output labels output 网络的全连接层的输出 值可能是有正有负的 例如 1 56 2 43 等 labels 正常标签 例如一共5个类别 值就是0 4
  • style-components使用

    目录 安装 创建全局样式文件 以js为后缀 组件中使用 为什么使用 style components style components最基础的用法就是以组件的形式编写样式 安装 npm install styled components 创
  • Qt 信号和槽函数

    信号和槽是一种高级接口 应用于对象之间的通信 它是 QT 的核心特性 当某个信号被发射 就需要调用与之相绑定的槽函数 这与Windows下的消息机制类似 消息机制是基于回调函数 一个回调即是一个函数的指针 因此如果希望一个处理函数通知一些事