Qt学习之路(9):深入了解信号槽

 Qt学习之路(9):深入了解信号槽
2009-09-06 18:27:48
标签: Qt  C++  学习  QT教程  教程
原创作品,允许转载,转载时请务必以超链接形式标明文章  原始出处 、作者信息和本声明。否则将追究法律责任。 http://devbean.blog.51cto.com/448512/199461
信号槽机制是Qt编程的基础。通过信号槽,能够使Qt各组件在不知道对方的情形下能够相互通讯。这就将类之间的关系做了最大程度的解耦。
 
槽函数和普通的C++成员函数没有很大的区别。它们也可以使virtual的;可以被重写;可以使public、protected或者private的;可以由其它的C++函数调用;参数可以是任何类型的。如果要说区别,那就是,槽函数可以和一个信号相连接,当这个信号发生时,它可以被自动调用。
 
connect()语句的原型类似于:
 
connect(sender, SIGNAL(signal), receiver, SLOT(slot));
 
这里,sender和receiver都是QObject类型的,singal和slot都是没有参数名称的函数签名。SINGAL()和SLOT()宏用于把参数转换成字符串。
 
深入的说,信号槽还有更多可能的用法,如下所示。
 
一个信号可以和多个槽相连:
 
connect(slider, SIGNAL(valueChanged( int)),
              spinBox, SLOT(setValue( int))); 
connect(slider, SIGNAL(valueChanged( int)),
               this, SLOT(updateStatusBarIndicator( int)));
 
注意,如果是这种情况,这些槽会一个接一个的被调用,但是它们的调用顺序是不确定的。
 
多个信号可以连接到一个槽:
 
connect(lcd, SIGNAL(overflow()),
               this, SLOT(handleMathError())); 
connect(calculator, SIGNAL(divisionByZero()),
               this, SLOT(handleMathError()));
 
这是说,只要任意一个信号发出,这个槽就会被调用。
 
一个信号可以连接到另外的一个信号:
 
connect(lineEdit, SIGNAL(textChanged( const QString &)),
               this, SIGNAL(updateRecord( const QString &)));
 
这是说,当第一个信号发出时,第二个信号被发出。除此之外,这种信号-信号的形式和信号-槽的形式没有什么区别。
 
槽可以被取消链接:
 
disconnect(lcd, SIGNAL(overflow()),
                  this, SLOT(handleMathError()));
 
这种情况并不经常出现,因为当一个对象delete之后,Qt自动取消所有连接到这个对象上面的槽。
 
为了正确的连接信号槽,信号和槽的参数个数、类型以及出现的顺序都必须相同,例如:
 
connect(ftp, SIGNAL(rawCommandReply( intconst QString &)),
               this, SLOT(processReply( intconst QString &)));
 
这里有一种例外情况,如果信号的参数多于槽的参数,那么这个参数之后的那些参数都会被忽略掉,例如:
 
connect(ftp, SIGNAL(rawCommandReply( intconst QString &)), 
             this, SLOT(checkErrorCode( int)));
 
这里,const QString &这个参数就会被槽忽略掉。
 
如果信号槽的参数不相容,或者是信号或槽有一个不存在,或者在信号槽的连接中出现了参数名字,在Debug模式下编译的时候,Qt都会很智能的给出警告。
 
在这之前,我们仅仅在widgets中使用到了信号槽,但是,注意到connect()函数其实是在QObject中实现的,并不局限于GUI,因此,只要我们继承QObject类,就可以使用信号槽机制了:
 
class Employee :  public QObject 

        Q_OBJECT  
public
        Employee() { mySalary = 0; }   
         int salary()  const {  return mySalary; } 
 
public slots: 
         void setSalary( int newSalary); 
 
signals: 
         void salaryChanged( int newSalary); 
 
private
         int mySalary; 
};
 
在使用时,我们给出下面的代码:
 
void Employee::setSalary( int newSalary) 

         if (newSalary != mySalary) { 
                mySalary = newSalary; 
                emit salaryChanged(mySalary); 
        } 
}
 
这样,当setSalary()调用的时候,就会发出salaryChanged()信号。注意这里的if判断,这是避免递归的方式!还记得前面提到的循环连接吗?如果没有if,当出现了循环连接的时候就会产生无限递归。

本文出自 “豆子空间” 博客,请务必保留此出处http://devbean.blog.51cto.com/448512/199461

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
详细目录 1. 序 2. Qt 简介 3. Hello, world! 4. 信号 5. 自定义信号 6. Qt 模块简介 7. MainWindow 简介 8. 添加动作 9. 资源文件 10. 对象模型 11. 布局管理器 12. 菜单栏、工具栏和状态栏 13. 对话框简介 14. 对话框数据传递 15. 标准对话框 QMessageBox 16. 深入 Qt5 信号新语法 17. 文件对话框 18. 事件 19. 事件的接受与忽略 20. event() 21. 事件过滤器 22. 事件总结 23. 自定义事件 24. Qt 绘制系统简介 25. 画刷和画笔 26. 反走样 27. 渐变 28. 坐标系统 29. 绘制设备 30. Graphics View Framework 31. 贪吃蛇游戏(1) 32. 贪吃蛇游戏(2) 33. 贪吃蛇游戏(3) 34. 贪吃蛇游戏(4) 35. 文件 36. 二进制文件读写 37. 文本文件读写 38. 存储容器 39. 遍历容器 40. 隐式数据共享 41. model/view 架构 42. QListWidget、QTreeWidget 和 QTableWidget 43. QStringListModel 44. QFileSystemModel 45. 模型 46. 视图和委托 47. 视图选择 48. QSortFilterProxyModel 49. 自定义只读模型 50. 自定义可编辑模型 51. 布尔表达式树模型 52. 使用拖放 53. 自定义拖放数据 54. 剪贴板 55. 数据库操作 56. 使用模型操作数据库 57. 可视化显示数据库数据 58. 编辑数据库外键 59. 使用流处理 XML 60. 使用 DOM 处理 XML 61. 使用 SAX 处理 XML 62. 保存 XML 63. 使用 QJson 处理 JSON 64. 使用 QJsonDocument 处理 JSON 65. 访问网络(1) 66. 访问网络(2) 67. 访问网络(3) 68. 访问网络(4) 69. 进程 70. 进程间通信 71. 线程简介 72. 线程和事件循环 73. Qt 线程相关类 74. 线程和 QObject 75. 线程总结 76. QML 和 QtQuick 2 77. QML 语法 78. QML 基本元素 79. QML 组件 80. 定位器 81. 元素布局 82. 输入元素 其他文章 宏定义中的 do {…} while (0) C++:在堆上创建对象,还是在栈上?

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值