第七章 探秘Qt的核心机制-信号与槽
第七章 探秘Qt的核心机制-信号与槽
注:要想使用Qt的核心机制信号与槽,就必须在类的私有数据区声明Q_OBJECT宏,然后会有moc编译器负责读取这个宏进行代码转化,从而使Qt这个特有的机制得到使用。
所谓信号槽,简单来说,就像是插销一样:一个插头和一个插座。当某种事件发生之后,比如,点击一下鼠标,或者按下某个按键,此时,这个组件就回发出一个信号。如果有一个槽,正好对应上这个信号,那么,这个槽函数就回被调用。
槽函数和普通的c++成员函数没有很大的区别,它们也可以是virtual的;可以被重写;可以使public、protected或者private的;可以被其他c++函数调用;参数可以是任何类型。槽函数可以和一个信号相连接,当这个信号发生时,它就被自动调用。
连接信号与槽是connect()函数,原型如下:
bool QObject::connect ( const QObject * sender, const QMetaMethod & signal, const QObject * receiver, const QMetaMethod & method, Qt::ConnectionType type = Qt::AutoConnection ) [static]
它可以把一个对象(sender)发送的信号(signal)和接收者(receiver)的槽函数(method)关联起来,这样当信号产生时与之关联的槽函数就会被执行。在connect函数里面我们用到了Qt提供的两个宏SIGNAL()和SLOT();这是Qt要求的,要关联信号和槽必须借助于这两个宏,两个宏的定义如下:
#define SLOT(name) "1"#name
#define SIGNAL(name) "2"#name
通过这两个宏,就可以把我们传递进去的槽和信号的名字转化成字符串,并在这两个字符串前面加上附加的字符。
如:
connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(myslots()));
经过moc处理后就变成:
connect(ui->pushButton, "2clicked()", this, "1myslots()");
connect函数的最后一个参数type可以指定传递信号的方式,它是Qt::ConnectionType枚举类型常量,常用连接类型如下表所列。
| Constant | Value | Description |
| Qt::AutoConnection | 0 | 当信号发送者和接收者处于同一线程内时,这个类型等同于DirectConnection,反之等同于QueuedConnection,这个类型也是connect函数的默认连接类型 |
| Qt::DirectConnection | 1 | 信号一旦发射,与之关联的槽函数立即执行 |
| Qt::QueuedConnection | 2 | 当信号产生,信号会暂时被缓冲到一个消息队列中,等待接收者的事件循环处理去队列中获取消息,然后执行和信号关联的槽函数,这种方式既可以在同一线程内传递消息也可以跨线程操作 |
| Qt::BlockingQueuedConnection | 4 | 这种类型类似于QueuedConnection,但是它只能应用于跨线程操作即发送者和接收者处于不同的线程中的情况,并且信号发送者线程会阻塞等待接收者的槽函数执行结束 |
| Qt::AutoCompatConnection | 3 | 当兼容Qt3程序是的默认连接类型 |
一个信号可以和多个槽相连(槽会一个接一个地被调用,但是调用的顺序是不确定的);
多个信号可以连接一个槽(只要任意一个信号产生,这个槽就回被调用);
一个信号可以连接到另一个信号;
槽可以被取消链接:
bool QObject::disconnect ( const QObject * sender, const QMetaMethod & signal, const QObject * receiver, const QMetaMethod & method ) [static]
这种情况并不经常出现,因为当一个对象delete之后,Qt自动取消所有连接到这个对象上面的槽。
要连接在一起的信号和槽,如果带了参数,那么这些参数的顺序和类型都要一致,并且信号带的参数的个数可以多于槽,信号在发射的时候可以把参数传递给槽函数接收,这也是不同对象交互数据的一个方法,信号可以发送多个类型的数据给槽函数,但是槽函数不一定需要全部接收处理,这样槽函数参数的个数可以少于或者等于信号参数的个数,但一定不能多于所连接信号的参数个数。为了正确的连接信号槽,信号和槽的参数类型以及出现的顺序必须相同。
下面举两个例子,一个例子是使用connect函数连接信号槽,另个例子是使用Qt Creator的designer来设置信号槽(本质还是connect,只是图形化)。
例子一:
#include <QAPPlication>
#include <QPushButton> int main (int argc, char *argv[])
{
QApplication app(argc, argv);
QPushButton *button = new QPushButton("Close");
QObject::connect(button, SIGNAL(clicked()), button, SLOT(close()));
button->show(); return app.exec();
}
输入以下指令编译:
qmake -project
qmake
make
运行程序:

点击按钮“Close”,窗口会关闭。
例子二:
使用Qt Creator创建一个工程

如何让界面在用户单击了“Close”按钮后立刻消失,当然是connect一下clicked和close就搞定了。接下来看具体怎么做?双击signalslotdialog.ui进入designer

拖放一个Push Button到空间放置区,并修改text属性为“Close”

单击Qt Creator的“编辑(Edit)”菜单,在弹出的子菜单里面点选“编辑信号/槽(Edit signals/slots)”,此时,当鼠标移动到“Close”按钮上时,按钮颜色变了。然后单击按钮,拖动鼠标到对话框的空白处,会看到下图所示界面

当松开鼠标左键,弹出“配置连接(Configure Connection)”对话框如图所示

设置如下图,单击“确定”

这样就connect了信号clicked和槽close

单击
编译运行出现如下界面

单击“Close”按钮,界面就退出。
第七章 探秘Qt的核心机制-信号与槽的更多相关文章
- 2.QT-窗口组件(QWidget),QT坐标系统,初探消息处理(信号与槽)
本章主要内容如下: 1) 窗口组件(QWidget) 2) QT坐标系统 3) 消息处理(信号与槽) 窗口组件(QWidget) 介绍 Qt以组件对象的方式构建图形用户界面 Qt中没有父组件的顶级组件 ...
- Qt对象模型之一:信号和槽
一.信号和槽机制概述 信号槽是 Qt 框架引以为豪的机制之一.所谓信号槽,实际就是观察者模式.当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal).这种发出是没有目 ...
- Qt Quick 事件处理之信号与槽
前面两篇文章<QML 语言基础>和<Qt Quick 简单教程>中我们介绍了 QML 语言的基本的语法和 Qt Quick 的常见元素,亲们,通过这两篇文章,您应该已经能够完毕 ...
- Qt Quick 事件处理之信号与槽(foruok的博客)
前面两篇文章<QML 语言基础>和<Qt Quick 简单教程>中我们介绍了 QML 语言的基本语法和 Qt Quick 的常见元素,亲们,通过这两篇文章,您应该已经可以完成简 ...
- Qt 和 Boost关于信号和槽的对比说明
对比 无论是 Qt 的实现方式还是 Boost 的实现方式,除了必须的定义信号和槽的类之外,都不需要额外的类. 两种实现都解决了类爆炸的问题.下面让我们对照着来看一下我们前面的分析. 两个不同的术语以 ...
- Qt 编程指南 3 信号和槽沟通
https://qtguide.ustclug.org/ 1 信号和槽 所谓信号槽,简单来说,就像是插销一样:一个插头和一个插座.怎么说呢?当某种事件发生之后,比如,点击了一下鼠标,或者按了某个按键, ...
- C/C++ -- Gui编程 -- Qt库的使用 -- 信号与槽的关联
Qt信号与槽的三种关联方法:1.设计界面关联,编辑信号/槽,自动关联 2.手动关联(1).头文件中定义槽 -----mywidget.h----- #ifndef MYWIDGET_H #define ...
- Qt Quick中的信号与槽
在QML中,在Qt Quick中,要想妥善地处理各种事件,肯定离不开信号与槽,本博的主要内容就是整理Qt 中的信号与槽的内容. 1. 链接QML类型的已知信号 QML中已有类型定义的信号分为两类:一类 ...
- QT(4)信号与槽
mainWidget.h #ifndef MAINWIDGET_H #define MAINWIDGET_H #include <QWidget> #include <QPushBu ...
随机推荐
- 【每日一摩斯】-Index Skip Scan Feature (212391.1)
INDEX Skip Scan,也就是索引快速扫描,一般是指谓词中不带复合索引第一列,但扫描索引块要快于扫描表的数据块,此时CBO会选择INDEX SS的方式. 官方讲的,这个概念也好理解,如果将复合 ...
- Dia Diagram Mac OSX Yosemite Fix 闪退 xterm
[转]http://navkirats.blogspot.hk/2014/10/dia-diagram-mac-osx-yosemite-fix-i-use.html I use the Dia to ...
- 提升 composer 的执行速读
常常遇到 php composer.phar update 等待一二十分钟还没有更新完成的情况. 提升速读的方法: 1. 升级PHP 版本到5.4以上 2. 删除文件夹Vender(或者重命名),之后 ...
- php引入公用部分html出现了一行空白(原创)
在导入公用部分html(客服信息)时,莫名其妙出现了一行空白,样式,html均无问题 后来才发现是html多了一行空白 <div class="ad-module-item3 fn-m ...
- PHP.7-HTML+CSS(一)-HTML语法、常用字符实体、颜色代码
HTML+CSS HTML是WEB页面的描述性语言,浏览器解释的语言 CSS则是为HTML制定样式的机制,为浏览器解释的语言.它不能独立使用,没有HTML就没有CSS,定义网页的外观和布局(字体.背景 ...
- Lastest Version Carprog Full V7.28 update and EEPROM reading
Carprog Full has recently launched the newest V7.28 (with all software activated and all 21items Ada ...
- linux编辑器 vi的使用
vi 编辑器的三个模式: 命令模式 开始就是命令模式 insert模式 i, I, a, A, o,O ,s, S 命令行模式 : i 在当前位置进入Insert模式 I 在行的头部进入Inser ...
- Android 自学之列表视图ListView和ListActivity
ListView是手机系统中使用非常广泛的一种组件,它以垂直列表的形式显示所有列表项. 创建ListView有两种方式: 直接使用ListView创建. 让Activity继承ListActivity ...
- javaweb学习总结五(内省、beanUtils工具包)
一:内省的概念 1:内省是反射的一种特例,由于在反射中频繁的操作javabean,所以为了方便反射 javabean,sun公司开发出一套API提高效率. 2:javaBean,就是用来封装客户端请求 ...
- LeetCode 80
Remove Duplicates from Sorted Array II Follow up for "Remove Duplicates": What if duplicat ...