信号和槽用于对象间的通讯。信号/槽机制是Qt的一个中心特征并且也许是Qt与其它工具包的最不相同的部分。
在图形用户界面编程中,我们经常希望一个窗口部件的一个变化被通知给另一个窗口部件。更一般地,我们希望任何一类的对象可以和其它对象进行通讯。例如,如果我们正在解析一个XML文件,当我们遇到一个新的标签时,我们也许希望通知列表视图我们正在用来表达XML文件的结构。
较老的工具包使用一种被称作回调的通讯方式来实现同一目的。回调是指一个函数的指针,所以如果你希望一个处理函数通知你一些事件,你可以把另一个函数(回调)的指针传递给处理函数。处理函数在适当的时候调用回调。回调有两个主要缺点。首先他们不是类型安全的。我们从来都不能确定处理函数使用了正确的参数来调用回调。其次回调和处理函数是非常强有力地联系在一起的,因为处理函数必须知道要调用哪个回调。

在Qt中我们有一种可以替代回调的技术。我们使用信号和槽。当一个特定事件发生的时候,一个信号被发射。Qt的窗口部件有很多预定义的信号,但是我们总是可以通过继承来加入我们自己的信号。槽就是一个可以被调用处理特定信号的函数。Qt的窗口部件又很多预定义的槽,但是通常的习惯是你可以加入自己的槽,这样你就可以处理你所感兴趣的信号。
信号和槽的机制是类型安全的:一个信号的签名必须与它的接收槽的签名相匹配。(实际上一个槽的签名可以比它接收的信号的签名少,因为它可以忽略额外的签名。)因为签名是一致的,编译器就可以帮助我们检测类型不匹配。信号和槽是宽松地联系在一起的:一个发射信号的类不用知道也不用注意哪个槽要接收这个信号。Qt的信号和槽的机制可以保证如果你把一个信号和一个槽连接起来,槽会在正确的时间使用信号的参数而被调用。信号和槽可以使用任何数量、任何类型的参数。它们是完全类型安全的:不会再有回调核心转储(core dump)。
从QObject类或者它的一个子类(比如QWidget类)继承的所有类可以包含信号和槽。当对象改变它们的状态的时候,信号被发送,从某种意义上讲,它们也许对外面的世界感兴趣。这就是所有的对象通讯时所做的一切。它不知道也不注意无论有没有东西接收它所发射的信号。这就是真正的信息封装,并且确保对象可以用作一个软件组件。

槽可以用来接收信号,但它们是正常的成员函数。一个槽不知道它是否被任意信号连接。此外,对象不知道关于这种通讯机制和能够被用作一个真正的软件组件。
你可以把许多信号和你所希望的单一槽相连,并且一个信号也可以和你所期望的许多槽相连。把一个信号和另一个信号直接相连也是可以的。(这时,只要第一个信号被发射时,第二个信号立刻就被发射。)
总体来看,信号和槽构成了一个强有力的组件编程机制。

一个最小的C++类声明:

    class Foo{public:Foo();int value() const { return val; }void setValue( int );private:int val;};

一个小的Qt类如下:

    class Foo : public QObject{Q_OBJECTpublic:Foo();int value() const { return val; }public slots:void setValue( int );signals:void valueChanged( int );private:int val;};

这个类有同样的内部状态,和公有方法来访问状态,但是另外它也支持使用信号和槽的组件编程:这个类可以通过发射一个信号,valueChanged(),来告诉外面的世界它的状态发生了变化,并且它有一个槽,其它对象可以发送信号给这个槽。
所有包含信号和/或者槽的类必须在它们的声明中提到Q_OBJECT。
槽可以由应用程序的编写者来实现。这里是Foo::setValue()的一个可能的实现:

    void Foo::setValue( int v ){if ( v != val ) {val = v;emit valueChanged(v);}}

这个类有同样的内部状态,和公有方法来访问状态,但是另外它也支持使用信号和槽的组件编程:这个类可以通过发射一个信号,valueChanged(),来告诉外面的世界它的状态发生了变化,并且它有一个槽,其它对象可以发送信号给这个槽。
    所有包含信号和/或者槽的类必须在它们的声明中提到Q_OBJECT。
槽可以由应用程序的编写者来实现。这里是Foo::setValue()的一个可能的实现:

    void Foo::setValue( int v ){if ( v != val ) {val = v;emit valueChanged(v);}}

emit valueChanged(v)这一行从对象中发射valueChanged信号。正如你所能看到的,你通过使用emit signal(arguments)来发射信号。
下面是把两个对象连接在一起的一种方法:

    Foo a, b;connect(&a, SIGNAL(valueChanged(int)), &b, SLOT(setValue(int)));b.setValue( 11 ); // a == undefined  b == 11a.setValue( 79 ); // a == 79         b == 79b.value();       

调用a.setValue(79)会使a发射一个valueChanged() 信号,b将会在它的setValue()槽中接收这个信号,也就是b.setValue(79) 被调用。接下来b会发射同样的valueChanged()信号,但是因为没有槽被连接到b的valueChanged()信号,所以没有发生任何事(信号消失了)。
注意只有当v != val的时候setValue()函数才会设置这个值并且发射信号。这样就避免了在循环连接的情况下(比如b.valueChanged() 和a.setValue()连接在一起)出现无休止的循环的情况。
这个例子说明了对象之间可以在互相不知道的情况下一起工作,只要在最初的时在它们中间建立连接。
预处理程序改变或者移除了signals、slots和emit 这些关键字,这样就可以使用标准的C++编译器。
在一个定义有信号和槽的类上运行moc。这样就会生成一个可以和其它对象文件编译和连接成引用程序的C++源文件。

转载于:https://www.cnblogs.com/new0801/p/6176961.html

Qt入门(3)——信号和槽相关推荐

  1. Qt eventFilter实现信号与槽

    对于Qt来说,信号与槽机制是其通信的一大亮点,但是Qt中也提供了其他的方法实现数据间的通信,如invokeMethod反射机制实现通信(https://blog.csdn.net/xx18030637 ...

  2. Qt工作笔记-信号与槽参数匹配问题

    今天,我把Qt3代码转化为Qt5,控件啥的都要换,李主任说了下为什么以前的信号和槽函数参数不匹配!!这句话让我对Qt中的信号与槽进一步有了了解. 下面的这个演示源码是基于这个博客的 https://b ...

  3. Qt的特性——信号和槽

    Qt的特性--信号和槽 1. Qt的特性 2. 信号和槽 2.1 信号和槽机制概述 2.2 典型应用示例 2.3 信号和槽的关联 2.4 断开关联 2.5 信号和槽的高级应用 1. Qt的特性 Qt在 ...

  4. QT学习之②信号与槽,以及链接实现方法

    QT学习之②信号与槽 ~QQ:3020889729 ~小蔡 信号与槽的意义 信号与槽的实质(文字:举例) 信号与槽的工作(图解) 信号与槽的创建 信号的声明 槽函数的声明 槽函数的实现 (无重载)信号 ...

  5. Qt中的信号与槽机制解析

    注:要想使用Qt的核心机制信号与槽,就必须在类的私有数据区声明Q_OBJECT宏,然后会有moc编译器负责读取这个宏进行代码转化,从而使Qt这个特有的机制得到使用. 所谓信号槽,简单来说,就像是插销一 ...

  6. Qt图形界面编程入门(信号和槽通信机制)

    信号和槽机制是Qt的核心机制,可以让编程人员将互不相关的对象绑定在一起,实现对象之间的通信. 声明了信号的对象,当其状态改变时,信号就由该对象发送出去,而且该对象只负责发送信号,它不知道另一端是谁在接 ...

  7. Qt for Python 信号和槽的使用详解

    前言 如果要说 Qt 里面的最常听到的词,那么 "信号"(signals)和"槽"(slots)绝对是其中之一了,其功能简单强大,想必每个 Qt 程序员最能理解 ...

  8. Qt中解决信号和槽不能使用自定义结构体的问题

    在Qt中信号和槽使用自定义的结构时,运行的时候发现报错不能识别结构体 解决办法: 一定要将自定义结构体定义为typedef struct 使用Q_DECLARE_METATYPE(结构体名),将结构体 ...

  9. PyQt入门(2)-信号和槽

    信号和槽用于对象之间的通信. 信号和槽机制是 Qt 的核心特性,可能也是与其他框架最不同的地方.Qt 的元对象系统使信号和槽成为可能. 在 GUI 编程中,当我们更改一个 widget 时,我们通常希 ...

  10. QT学习之信号和槽,图片的添加

    信号和槽 给控件改名字 为了分析代码方便,我们要给控件改名字,要通俗易懂. 例如:双击登陆后鼠标会选中右边的logoBt,即可修改名称. 什么是信号和槽 信号:信号就是指控件发出的特定信号. 比如按钮 ...

最新文章

  1. “嫁”给程序媛,走上人生巅峰
  2. 存储过程执行不报错,时间太快,但是执行无效
  3. 【杂谈】从学员到参与书籍写作,我在有三AI学习与成长的故事
  4. Java怎么学?在学Java的过程中要注意些什么呢?
  5. 如何用Excel统计出各科指定分数段的人数?(亲测)
  6. hadoop关联文件处理
  7. 手机浏览器网址_打开URL(在其他应用中访问网址)app下载-打开URL(在其他应用中访问网址)v2.6安卓版下载...
  8. 探讨 | SpringBoot + MyBatis 多数据源事物问题
  9. Linux中sql*loader-350,SqlLoader
  10. CC2540/CC2541蓝牙4.0BLE协议栈开发
  11. PNG图片压缩原理--屌丝的眼泪 #1
  12. html文件导入到u盘中,技术分享 - 编程实现U盘插入自动复制U盘内容到本地
  13. 论文格式设置-页面设置、页眉页脚、自动生成目录等
  14. 设计模式之单例设计模式初步
  15. 【面经】数据分析岗_面试题整理总结(持续更新中…)
  16. 扇贝python编程课_扇贝编程APP下载|扇贝编程python V1.1.35 安卓版下载 - 下载银行...
  17. hbuilder 断点_Hbuilder配置php断点调试
  18. android实现系统状态栏的隐藏方法,Android隐藏系统状态栏(沉浸式状态栏)和设置状态栏颜色...
  19. 二叉排序树,平衡二叉树和哈夫曼树
  20. win10 android驱动问题,WIN10 64位 android驱动无法安装

热门文章

  1. JQuery动态创建Form
  2. uniapp开发微信小程序时,报错:Now you can provide attr `wx:key` for a `wx:for` to improve performance
  3. 【eclipse】配置author和commiter,git配置user.name和user.email
  4. 【SSL】错误java.security.UnrecoverableKeyException: Cannot recover key
  5. docker 不挂断创建容器
  6. 设计模式(三)--适配器模式
  7. Matlab 预防性维修,使用 MATLAB 进行预测性维护简介
  8. html怎样使图片不占位子,复式客厅上阁楼楼梯安装什么位置不占地方 最节约空间的阁楼楼梯设计图片...
  9. matlab操作入门实验报告,matlab操作实验报告
  10. 终于看腻了黄色!让它五彩斑斓起来!