1. 信号和槽概述

> 信号槽是 Qt 框架引以为豪的机制之一。所谓信号槽,实际就是观察者模式(发布-订阅模式)。当某个`事件`发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣,它就会使用连接(connect)函数,意思是,将想要处理的信号和自己的一个函数(称为槽(slot))绑定来处理这个信号。也就是说,当信号发出时,被连接的槽函数会自动被回调。这就类似观察者模式:当发生了感兴趣的事件,某一个操作就会被自动触发。

1.1 信号的本质

信号是由于用户对窗口或控件进行了某些操作,导致窗口或控件产生了某个特定事件,这时候Qt对应的窗口类会发出某个信号,以此对用户的挑选做出反应。

因此根据上述的描述我们得到一个结论:信号的本质就是事件,比如:

  • 按钮单击、双击

  • 窗口刷新

  • 鼠标移动、鼠标按下、鼠标释放

  • 键盘输入

那么在Qt中信号是通过什么形式呈现给使用者的呢?

  • 我们对哪个窗口进行操作, 哪个窗口就可以捕捉到这些被触发的事件。
  • 对于使用者来说触发了一个事件我们就可以得到Qt框架给我们发出的某个特定信号。
  • 信号的呈现形式就是函数, 也就是说某个事件产生了, Qt框架就会调用某个对应的信号函数, 通知使用者。

在QT中信号的发出者是某个实例化的类对象,对象内部可以进行相关事件的检测。

1.2 槽的本质

在Qt中槽函数是一类特殊的功能的函数,在编码过程中也可以作为类的普通成员函数来使用。之所以称之为槽函数是因为它们还有一个职责就是对Qt框架中产生的信号进行处理。

举个简单的例子:

女朋友说:“我肚子饿了!”,于是我带她去吃饭。

上边例子中相当于女朋友发出了一个信号, 我收到了信号并其将其处理掉了。

  • 女朋友 -> 发送信号的对象, 信号内容: 我饿了
  • 我 -> 接收信号的对象并且处理掉了这个信号, 处理动作: 带她去吃饭

在Qt中槽函数的所有者也是某个类的实例对象。

1.3 信号和槽的关系

在Qt中信号和槽函数都是独立的个体,本身没有任何联系,但是由于某种特性需求我们可以将二者连接到一起,相当于一个绑定,在Qt中我们需要使用QOjbect类中的connect函数进二者的关联。

QMetaObject::Connection QObject::connect(
const QObject *sender, PointerToMemberFunction signal,
const QObject *receiver, PointerToMemberFunction method,
Qt::ConnectionType type = Qt::AutoConnection);
- 参数:
- sender: 发出信号的对象
- signal: 属于sender对象, 信号是一个函数, 这个参数的类型是函数指针, 信号函数地址
- receiver: 信号接收者
- method: 属于receiver对象, 当检测到sender发出了signal信号,
receiver对象调用method方法,信号发出之后的处理动作 // connect函数相对于做了信号处理动作的注册
// 调用conenct函数的sender对象的信号并没有产生, 因此receiver对象的method也不会被调用
// method槽函数本质是一个回调函数, 调用的时机是信号产生之后, 调用是Qt框架来执行的
// connect中的sender和recever两个指针必须被实例化了, 否则conenct不会成功
connect(const QObject *sender, &QObject::signal,
const QObject *receiver, &QObject::method);

1.4 通过实例加深理解

  • 现在要实现一个简单的功能,就说创建一个按钮,点击这个按钮关闭窗口

然后思考,这个功能的信号发出者,信号接受者,以及发出什么信号,接受信号后怎么做

  • 按钮: 信号发出者 -> QPushButton
  • 窗口: 信号的接收者和处理者 -> QWidget
  • 发出信号:被点击 -> clicked
  • 槽函数,即如何处理 -> close
  • 现在我们来实现一下

在ui中添加一个button,取名为closeBtn

然后再Mainwindow.cpp 文件中

#include "mainwindow.h"
#include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this); connect(ui->closeBtn,&QPushButton::clicked,this,&MainWindow::close);
} MainWindow::~MainWindow()
{
delete ui;
}

注意这条语句

connect(ui->closeBtn,&QPushButton::clicked,this,&MainWindow::close);

通过这条语句来实现绑定

  • 现在我们来运行一下

点击按钮,窗口关闭

这只是一个很简单的例子,用来帮助理解信号槽,希望对你有帮助。

Qt信号槽机制理解的更多相关文章

  1. QT源码之Qt信号槽机制与事件机制的联系

    QT源码之Qt信号槽机制与事件机制的联系是本文要介绍的内容,通过解决一个问题,从中分析出的理论,先来看内容. 本文就是来解决一个问题,就是当signal和slot的连接为Qt::QueuedConne ...

  2. QT信号槽机制

    信号槽 信号槽是QT中用于对象间通信的一种机制,也是QT的核心机制.在GUI编程中,我们经常需要在改变一个组件的同时,通知另一个组件做出响应.例如: 一开始我们的Find按钮是未激活的,用户输入要查找 ...

  3. Qt信号槽机制的实现(面试的感悟,猜测每一个类保存的一个信号和槽的二维表,实际使用函数指针 元对象 还有类型安全的检查设定等等)

    因为面试时问了我这道题,导致我想去了解信号槽到底是如何实现的,于是贴着顺序看了下源码,大致了解了整个框架.网上关于信号槽的文章也很多,但是大部分都是将如何应用的,这里我就写一下我所理解的如何实现吧, ...

  4. Qt信号槽-原理分析

    目录 一.问题 二.Moc 1.变量 2.Q_OBJECT展开后的函数声明 3.自定义信号 三.connect 四.信号触发 1.直连 2.队列连接 五.总结 六.推荐阅读 一.问题 学习Qt有一段时 ...

  5. QT学习记录之理解信号槽机制

    作者:朱金灿 来源:http://blog.csdn.net/clever101 QT的事件机制采用的信号槽机制.所谓信号槽机制,简而言之就是将信号和信号处理函数绑定在一起,比如一个按钮被单击是一个信 ...

  6. C++11实现Qt的信号槽机制

    概述 Qt的信号槽机制是Qt的核心机制,按钮点击的响应.线程间通信等都是通过信号槽来实现的,boost里也有信号槽,但和Qt提供的使用接口很不一样,本文主要是用C++11来实现一个简单的信号槽,该信号 ...

  7. VJGUI消息设计-兼谈MFC、QT和信号/槽机制

    星期六下午4点,还在公司加班.终于写完了下周要交工的一个程序. 郁闷,今天这几个小时写了有上千行代码吧?虽然大部分都是Ctrl-C+Ctrl-V,但还是郁闷. 作为一个有10年经验的MFC程序员,郁闷 ...

  8. Qt学习记录--02 Qt的信号槽机制介绍(含Qt5与Qt4的差异对比)

    一 闲谈: 熟悉Window下编程的小伙伴们,对其消息机制并不陌生, 话说:一切皆消息.它可以很方便实现不同窗体之间的通信,然而MFC库将很多底层的消息都屏蔽了,尽管使用户更加方便.简易地处理消息,但 ...

  9. Qt开发之信号槽机制

    一.信号槽机制原理 1.如何声明信号槽 Qt头文件中一段的简化版: class Example: public QObject { Q_OBJECT signals: void customSigna ...

随机推荐

  1. .NET并发编程-TPL Dataflow并行工作流

    本系列学习在.NET中的并发并行编程模式,实战技巧 本小节了解TPL Dataflow并行工作流,在工作中如何利用现成的类库处理数据.旨在通过TDF实现数据流的并行处理. TDF Block 数据流由 ...

  2. 【JavaScript】Leetcode每日一题-二叉搜索树的范围和

    [JavaScript]Leetcode每日一题-二叉搜索树的范围和 [题目描述] 给定二叉搜索树的根结点 root,返回值位于范围 [low, high] 之间的所有结点的值的和. 示例1: 输入: ...

  3. layui中流加载layui.flow

    1.引入layui.css和layui.js 2. html中定义容器 <div id="demo"></div> js部分: layui.use('flo ...

  4. 数据人必读!玩转数据可视化用这个就够了——高德LOCA API 2.0升级来袭!

    引言 "一图胜千言",大数据时代来临,数据与人们生活密切相关.复杂难懂且体量庞大的数据给人的感觉总是冷冰冰的,让人难以获取到重点信息,也找不出规律和特征,数据价值发挥不出来.空间数 ...

  5. Mybatis学习之自定义持久层框架(一) 为什么要用框架而不直接用JDBC?

    前言 说起Mybatis,相信大家都不会感到陌生,它是一款优秀的持久层框架,应用于java后端开发中,为客户端程序提供访问数据库的接口. 我们都知道,JDBC是Java语言中用来规范客户端程序如何来访 ...

  6. 自定义元类 __call__,__init__,__new__总结

    只要对象能被调用 产生对象的类里必然有__call__方法 在调用类时,必定先触发type里的__call__ __call__下有: 1.产生对象的object.__new__ 2..被调用的类自己 ...

  7. 关于在pycharm上使用git(保姆级别教程)

    文件 → 设置 先在pycharm上面登录github账号,版本控制 → GitHub → '+' → 通过GitHub登录 会自动跳转至浏览器,然后点击"Authorize in GitH ...

  8. 通过Dapr实现一个简单的基于.net的微服务电商系统(十三)——istio+dapr构建多运行时服务网格之生产环境部署

    之前所有的演示都是在docker for windows上进行部署的,没有真正模拟生产环境,今天我们模拟真实环境在公有云上用linux操作如何实现istio+dapr+电商demo的部署. 目录:一. ...

  9. [笔记] 《c++ primer》显示器程序 Chapter7

    补充Sales_data没有体现出的其他类特性 Screen.h 1 #include <string> 2 #include <iostream> 3 4 class Scr ...

  10. [Java] Structs

    背景 基于MVC的WEB框架 在表示层过滤访问请求并处理 步骤 在eclipse中创建Web动态项目 导入相关jar包到WEB-INF/lib 在WEB-INF目录下新建web.xml,配置Filte ...