libsigc++库的使用
Libsigc++库的使用
概述
通常在图形用户界面程序中,我们希望检测事件的代码与处理事件的代码能够分开独立出来。我们可以使用回调函数的机制,注册函数指针来注册相关的处理函数,不过,在C++中,我们可以使用类型安全的库libsigc++。
Libsigc++库中提出了槽的概念,熟悉Qt的朋友应该对槽的概念不陌生,它其实是指向一个可作为回调的函数的引用,以下三种类型的函数都可作为槽:
1. 普通函数。
2. 重载了operator()的函数子对象(类)。
3. 如果对象所属的类继承了sigc::trackable, 它的成员函数也可以作为槽。
针对第三种类型的函数,libsigc++库提供了sigc::ptr_func()和sigc::mem_func()为分别从类的静态函数和对象的成员函数中创建槽。返回值类型是signal::slot,可通过emit()或operator()调用。另外,libsigc++也提出了信号的概念signals,它是模板类型sigc::signal实例, 可将信号与槽连接起来,当emit信号时,所有连接到信号的槽将会执行。
一个简单的示例
Signal发送方:
class AlienDetector { public: AlienDetector() { } void run() { cout<<"AlienDetector is running"<<endl; // signal_detected.emit(); signal_detected(); } sigc::signal<void> signal_detected; }; |
槽函数定义,与信号的返回值类型一致:
void warn_people() { cout<<"There are aliens in the carpark!"<<endl; } |
连接信号和槽:
int main() { AlienDetector mydetector; mydetector.signal_detected.connect(sigc::ptr_fun(warn_people)); mydetector.run(); return 0; } |
头文件包含:
#include <iostream> #include <sigc++/sigc++.h> |
编译:
g++ example1.cc -o example1 `pkg-config --cflags --libs sigc++-2.0` |
使用成员函数作为槽
上述例子演示了普通函数作为槽函数,接下来的例子将显示如何将成员函数作为槽使用。
提供槽函数的类定义如下,必须从sigc::trackable继承:
class AlienAlerter : public sigc::trackable { public: AlienAlerter(char const* servername) { srvname = string(servername); } void alert() { cout<<"server name: "<<srvname<<endl; } private: // ... string srvname; }; |
连接信号和槽
int main() { AlienDetector mydetector; AlienAlerter myalerter("localhost"); mydetector.signal_detected.connect(sigc::mem_fun(myalerter, &AlienAlerter::alert)); mydetector.run(); return 0; } |
带参数的信号
信号的类型sigc::signal的模板参数中第一个是返回值类型,后面都是信号参数的类型,如:
sigc::signal<void, std::string> |
那么对应的槽函数声明也必须为返回值为void, 接受一个参数为std::string的函数,即:
void warn_people(std::string where) { cout << "There are aliens in " << where << "!" << endl; } |
如前述AlienDetector类的声明修改如下:
class AlienDetector { public: AlienDetector(); void run(); sigc::signal<void, std::string> signal_detected; // changed }; |
连接信号和槽:
int main() { AlienDetector mydetector; mydetector.signal_detected.connect( sigc::ptr_fun(warn_people) ); mydetector.run(); return 0; } |
断开信号和槽之间的连接
信号sigc::signal的connect方法的返回值类型为:sigc::connection, 它提供了一个disconnect函数来断开信号和槽之间的连接。
高级话题
重新绑定(rebinding)
当信号与槽的类型不匹配时,连接时会出现编译错误。为了解决这种不匹配的情况,我们可以利用sigc::bind进行重绑定,便信号与槽之间的类型能够重新匹配。
假设我们定义了除返回值外, 不带任何参数的信号,这样与之连接的槽函数也不能接受任何参数。如果我们要利用一个已经写好的并需要传入参数的函数,我们可以通过sigc::bind作些处理,如下所示:
myaliendetector.signal_detected.connect(sigc::bind( sigc::ptr_fun(warn_people), "the carpark" ) ); |
其中sigc::bind(slot, arg), 如果槽函数接受多个参数,那么arg指的是最右边那个参数。
另外,返回值的类型也可以通过类似的方式重新绑定:
sigc::bind_return(slot, returnvalue) |
反过来,如果我们要利用一个已存在的函数作为槽函数,它接受一个参数,但是信号要求槽函数不接受任何参数,可以通过如下方式进行重新绑定:
myaliendetector.signal_detected.connect( sigc::hide<std::string>( sigc::ptr_fun(warn_people) ) ); |
,如果有多个参数,如上写法隐藏的是最右边的参数。
类型重定义(Retyping)
另一种情况是,当信号接受一个整型参数,但我们想让它与一个接受双精度类型的槽函数连接,这时需要进行类型重定义,可以通过sigc::retype模板类型,它与sigc::signal的模板参数一样。
void dostuff(double foo) { } sigc::signal<void,int> asignal; asignal.connect( sigc::retype<void, int>( slot(&dostuff) ) ); |
当只是返回类型不同时,则只需指定返回类型参数。
转载于:https://my.oschina.net/fuyajun1983cn/blog/263851
libsigc++库的使用相关推荐
- kurento代码分析(一)C++与C的交互
简单阅读了下kurento的代码,因为自身也是小白,许多地方也是一知半解的.它的代码不容易理清逻辑,它采用gstreamer的流媒体处理框架,信令处理部分主要由c++负责,而媒体处理部分则由c层的g ...
- Windows API参考大全
第一章 Win32 API概论 1.1为什么使用 Wu32 API 在Windows程序设计领域处于发展初期时,Windows程序员可使用的编程工具唯有API 函数.这些函数在程序员手中犹如" ...
- 中标麒麟 NeoKylin-SDK 里都有哪些库文件
** 中标麒麟 NeoKylin-SDK 里都有哪些库文件 ** 下边是中标麒麟 1-8 和14的安装包内容.希望对中标麒麟开发的同学能有些帮助. [root@bogon NeoKylin-SDK]# ...
- c++ 工具库 (zz)
下面是收集的一些开发工具包,主要是C/C++方面的,涉及图形.图像.游戏.人工智能等各个方面,感觉是一个比较全的资源.供参考! 原文的出处:http://www.codemonsters.de/hom ...
- 【C/C++开发】c++ 工具库 (zz)
下面是收集的一些开发工具包,主要是C/C++方面的,涉及图形.图像.游戏.人工智能等各个方面,感觉是一个比较全的资源.供参考! 原文的出处:http://www.codemonsters.de/ho ...
- C++ 100款开源界面库——内容细节(现在有变动)不必深究,普及就好
C++ 100款开源界面库 (10) from:http://www.cnblogs.com/Alberl/p/3375162.html (声明:Alberl以后说到开源库,一般都是指著名的.或者不著 ...
- 仿迅雷播放器教程 -- C++ 100款开源界面库 (10)
(声明:Alberl以后说到开源库,一般都是指著名的.或者不著名但维护至少3年以上的.那些把代码一扔就没下文的,Alberl不称之为开源库,只称为开源代码.这里并不是贬低,像Alberl前面那个系列的 ...
- Go 编译的可执行文件是否有动态库链接?
Go 引用了其他包的话,是将引用的包都编译进去.用 ldd 看几个 Go 编译出来的二进制程序有的没有动态链接库的使用.但是有的又有引用动态链接库,这个是为什么? 回答:Go 默认是开启 CGO_EN ...
- Go 学习笔记(78)— Go 标准库 net/http 创建服务端(接收 GET、POST 请求)
使用 net/http 标准库创建一个 http 的 restful api 的服务端,用来处理 GET.POST 等请求. 源代码如下: package mainimport ("enco ...
最新文章
- cocos2d-x android 黑屏,cocos2d-x-3.8生成android 的apk后真机测试出现黑屏
- php微服务架构设计模式,《微服务架构设计模式》读书笔记---第十一章:开发面向生产环境的微服务应用...
- 4.1 Tensorflow:卷积函数
- 李开复悔过:把运营微博当人生,把获取粉丝当游戏
- GPUImage API 文档之GPUImagePicture类
- “约见”面试官系列之常见面试题第十四篇之所有数据类型(建议收藏)
- SVN工作笔记001---svn删除已经上传的文件
- 自己动手写个小框架之三
- [转载] python 去除字符串的标点符号 用_Python成为专业人士笔记–String字符串方法
- 【转】Android 平台下使用 i2c-tools
- sql server 2005_全文目录
- 使用 Android 签名 APK
- Linux怎么运行lisp,Lisp - Ubuntu 中的编程语言_Linux编程_Linux公社-Linux系统门户网站...
- R3Det: Refined Single-Stage Detector with Feature Refinementfor Rotating Object论文学习
- 互联网自动化赚钱的方法
- java中length 的用法
- 常用SQL语句 - 基于MySQL数据库
- Android开发——底部导航栏设计
- 你的企业是否需要首席数字官?
- [zz]各大IT公司待遇