信号槽库:sigslot.h和sigc++使用

简介: 用qt的知道,qt有方便简单的信号槽机制,但需要专门的qt工具处理。 如果想直接使信号槽就可以使用sigslot库,或者sigc++库,或者boost中的signals,这里介绍sigslot和sigc++库。

用qt的知道,qt有方便简单的信号槽机制,但需要专门的qt工具处理。 
如果想直接使信号槽就可以使用sigslot库,或者sigc++库,或者boost中的signals,这里介绍sigslot和sigc++库。

sigslot.h:只有一个头文件,使用简单方便。 
sigc++:包含文件多,但功能更强大。


sigslot库

官方地址

http://sigslot.sourceforge.net/

在vs2013中使用

  • 包含头文件
#include "sigslot.h"
  • 1
  • 1
  • 改动:
    //在sigslot.h的420,将:
typedef sender_set::const_iterator const_iterator;
    //改为:
typedef typename sender_set::const_iterator const_iterator;
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

基本使用:

  • signal0~signal8:信号类:作为类成员
    class mySg
    {
        sigc::signal0<> sg1; // 无参数 sigc::signal2<char*, double> sg2; // 2个参数 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5
  • connection 
    槽函数:作为类成员,类需要继承has_slots<>,且槽函数的返回值必须是void类型
    class mySlot: public : has_slots<>
    {
    public:
        void on_func1(){}                       // 无参数,与信号对应 void on_func2(char*, double)(){} // 2个参数 }; mySg sig; mySlot slt; sig.sg1.conncent(&slt,&mySlot::on_func1); sig.sg2.conncent(&slt,&mySlot::on_func2);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • disconnection 
    解除连接:可以使用disconnect()和disconnect_all()
    sig.sg1.disconnect(&slt);
    sig.sg1.disconnect_all();
  • 1
  • 2
  • 1
  • 2
  • emiting 
    发送信号:可以直接使用()运算符,也可以调用signal的emit函数
    sig.sg1.emit();
    sig.sg2("str",0.1);
  • 1
  • 2
  • 1
  • 2

实例:

#include <stdio.h>
#include <conio.h>
#include <cstdlib>
#include <iostream>
using namespace std; #include "sigslot.h" using namespace sigslot; #define pause_wait() {std::cout << "\nPlease press any key to continue.\n";_getch();} // class enum ObjState{Normal = 0, Hidden = 1}; class ObjectBase : public has_slots<> { public: ObjectBase(){ px = 0; py = 0; state = Normal; } ObjectBase(const int &x, const int &y):px(x), py(y){ state = Normal; } ~ObjectBase(){}; void onMoveBy(const int &x, const int &y){px += x; py += y;} void onResize(const int &x, const int &y){px = x; py = y;} void onSetState(ObjState s){this->state = s;} void onPrintState() { if(state == Normal) std::cout << "Normal" << std::endl; else if(state == Hidden) std::cout << "Hidden" << std::endl; else std::cout << "Error: error state value" << std::endl; } const int& getX(){return px;} const int& getY(){return py;} const char* getState() { if(state == Normal) return "Normal"; else if(state == Hidden) return "Hidden"; else return nullptr; } private: ObjState state; int px; int py; }; class Control { public: signal2<const int&, const int&> moveBy; signal2<const int&, const int&> resize; signal1<ObjState> setState; signal0<> printState;; }; int main(int argc, char* argv[]) { ObjectBase obj(10,10); Control ctrl; #if(1) ctrl.moveBy.connect(&obj, &ObjectBase::onMoveBy); ctrl.resize.connect(&obj, &ObjectBase::onResize); ctrl.setState.connect(&obj, &ObjectBase::onSetState); ctrl.printState.connect(&obj, &ObjectBase::onPrintState); //ctrl.moveBy.disconnect(&obj); //ctrl.moveBy.disconnect_all(); // start pro loop PRO_Start: while(true) { system("cls"); cout << "Object Information" << endl; cout << "\t Position_x: " << obj.getX() << endl; cout << "\t Position_y: " << obj.getY() << endl; cout << "\t State: " << obj.getState() << endl; cout << "\n"; cout << "\t m: move object \n" "\t r: resize object \n" "\t s: set object state \n" "\t p: print object state \n" << endl; cout << "Input:"; char ch = getchar(); switch(ch) { case 'm': // move ctrl.moveBy(10,10); break; case 'M': ctrl.moveBy.emit(-20,-20); break; case 'R': case 'r': // resize ctrl.resize.emit(0, 0); break; case 'P': case 'p': // printState goto PRO_PrintState; break; case 's': // setState ctrl.setState(Normal); break; case 'S': ctrl.setState.emit(Hidden); break; case 'Q': case 'q': // exit goto PRO_Exit; break; default: break; } } PRO_PrintState: ctrl.printState.emit(); pause_wait(); goto PRO_Start; #endif pause_wait(); PRO_Exit: return 0; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139

sigc++库

官方地址

http://libsigc.sourceforge.net/

编译

可以在http://download.csdn.net/detail/yehuohan/9600368下载已经编好的库文件,2.8.0版 
注意1:在用高版本编译时,如2.8.0,可能会提示找不到msvc_recommended_pragmas.h,可以在vs的

属性 -> C/C -> 高级 -> 强制包含文件
  • 1
  • 1

去掉msvc_recommended_pragmas.h,或者添加一个msvc_recommended_pragmas.h文件,在http://download.csdn.net/detail/yehuohan/9600369的源代码时已经放入了该文件。 
注意2:在使用高版本(如2.9.7)编译时,若提示找不到slot.cc等文件,可以使用低版本中的放入相应位置即可。

在vs中使用

* 项目 -> VC++目录 -> 包含目录: 添加 sigc++所在的目录
* 添加下列代码:
        #include <sigc++/sigc++.h>
        #ifdef _DEBUG
            #pragma comment(lib,"sigcd.lib")
        #else #pragma comment(lib,"sigc.lib") #endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

基本使用:

  • signal 
    信号类:可以作为其它类成员,也可直接定义
    //返回值: int,2个参数:char*, double,参数个数可以直接指定
    sigc::signal<int, char*, double> sg1; sigc::signal2<int, char*, double> sg2; class mySg { sigc::signal2<int, char*, double> sg3; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • connection 
    连接槽函数,作为类成员时,要继承sigc::trackable; 
    ptr_fun, ptr_fun0~7 : 连接全局函数; 
    mem_fun, mem_fun0~7 : 连接类成员函数; 
    ptr_fun,mem_fun与signal之间只要参数类型对应就可连接, 并非一定要数字对应(如:ptr_fun3并非一定要与signal3对应连接)
    sigc::connection ccSg1 = sg1.connect(sigc::ptr_fun(&func1));
    class mySlot: public : sigc::trackable
    {
    public:
        int func2(char*, double)(){} } obj; sigc::connection ccSg2 = sg2.connect(sigc::mem_fun2(obj,&mySlot::func)); class mySg: public : sigc::trackable { mySg(){auto ccIter_Sg3 = sg3.connect(sigc::mem_fun(*this,&mySg::on_func));} sigc::signal2<int, char*, double> sg3; int on_func(char*, double)(){} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • disconnection 
    如果不需要解连接,可以不用定义sigc::connection
    ccSg1.disconnect();
    ccSg2.disconnect();
  • 1
  • 2
  • 1
  • 2
  • emiting 
    // 发送信号:调用signal的emit函数
    sg1.emit("str",0.1);
    sg2.emit("str",0.1);
  • 1
  • 2
  • 1
  • 2

实例:

#include <stdio.h>
#include <conio.h>
#include <cstdlib>
#include <iostream>
using namespace std; #include <sigc++/sigc++.h> #ifdef _DEBUG #pragma comment(lib,"sigc280d.lib") #else #pragma comment(lib,"sigc280.lib") #endif // _DEBUG #define pause_wait() {std::cout << "\nPlease press any key to continue.\n";_getch();} // class enum ObjState{Normal = 0, Hidden = 1}; class ObjectBase : public sigc::trackable { public: ObjectBase(){ px = 0; py = 0; state = Normal; setConnection(); } ObjectBase(const int &x, const int &y) :px(x), py(y){ state = Normal; setConnection(); } ~ObjectBase(){}; sigc::signal<void,const char*> putMsg; void onMoveBy(const int &x, const int &y){px += x; py += y;} void onResize(const int &x, const int &y){px = x; py = y;} void onSetState(ObjState s){this->state = s;} void onPrintState() { if(state == Normal) std::cout << "Normal" << std::endl; else if(state == Hidden) std::cout << "Hidden" << std::endl; else std::cout << "Error: error state value" << std::endl; } const int& getX(){return px;} const int& getY(){return py;} const char* getState() { if(state == Normal) return "Normal"; else if(state == Hidden) return "Hidden"; else return nullptr; } private: ObjState state; int px; int py; void printMsg(const char* str){std::cout << str << std::endl; } void setConnection() { putMsg.connect(sigc::mem_fun(*this, &ObjectBase::printMsg)); } }; class Control { public: Control(){} sigc::signal<void, const int&, const int&> moveBy; sigc::signal2<void, const int&, const int&> resize; // return void type, and 2 parameters sigc::signal<void, ObjState> setState; private: }; // print word steped by space int printSpaceStr(const char* str) { int cnt = 0; const char* p = str; char ch; std::cout << endl; do { ch = *p; cout << ch << ' '; cnt++; } while (*++p != '\0'); std::cout << endl; return cnt; } int main(int argc, char* argv[]) { ObjectBase obj(0, 0); Control ctrl; sigc::signal1<int, const char*> printSS; sigc::connection ccPrintSS = printSS.connect(sigc::ptr_fun1(&printSpaceStr)); //ccPrintSS.disconnect(); sigc::signal0<void> printState; printState.connect(sigc::mem_fun(obj, &ObjectBase::onPrintState)); ctrl.moveBy.connect(sigc::mem_fun(obj, &ObjectBase::onMoveBy)); ctrl.resize.connect(sigc::mem_fun(obj, &ObjectBase::onResize)); auto ccIter_SetState = ctrl.setState.connect(sigc::mem_fun(obj, &ObjectBase::onSetState)); //ccIter_SetState->disconnect(); // start pro loop PRO_Start: while(true) { system("cls"); obj.putMsg.emit("Object Information"); cout << "\t Position_x: " << obj.getX() << endl; cout << "\t Position_y: " << obj.getY() << endl; cout << "\t State: " << obj.getState() << endl; cout << "\n"; cout << "\t m: move object \n" "\t r: resize object \n" "\t s: set object state \n" "\t p: print object state \n" "\t a: print space word \n" << endl; cout << "Input:"; char ch = getchar(); switch(ch) { case 'm': // move ctrl.moveBy.emit(10,10); break; case 'M': ctrl.moveBy.emit(-20,-20); break; case 'R': case 'r': // resize ctrl.resize.emit(0, 0); break; case 'P': case 'p': // printState goto PRO_PrintState; break; case 's': // setState ctrl.setState.emit(Normal); break; case 'S': ctrl.setState.emit(Hidden); break; case 'A': case 'a': goto RPO_PrintSpaceStr; break; case 'Q': case 'q': // exit goto PRO_Exit; break; default: break; } } PRO_PrintState: printState.emit(); pause_wait(); goto PRO_Start; RPO_PrintSpaceStr: printSS.emit("Sigc_Demo"); pause_wait(); goto PRO_Start; PRO_Exit: return 0; }
目录
相关文章
|
12天前
|
存储 C++ 容器
C++STL(标准模板库)处理学习应用案例
【4月更文挑战第8天】使用C++ STL,通过`std:vector`存储整数数组 `{5, 3, 1, 4, 2}`,然后利用`std::sort`进行排序,输出排序后序列:`std:vector<int> numbers; numbers = {5, 3, 1, 4, 2}; std:sort(numbers.begin(), numbers.end()); for (int number : numbers) { std::cout << number << " "; }`
17 2
|
24天前
|
算法 编译器 C语言
【C++ 异常】C++ 标准库异常类及其应用
【C++ 异常】C++ 标准库异常类及其应用
17 0
|
24天前
|
缓存 算法 C语言
【C++ 标准查找算法 】C++标准库查找算法深入解析(In-depth Analysis of C++ Standard Library Search Algorithms)
【C++ 标准查找算法 】C++标准库查找算法深入解析(In-depth Analysis of C++ Standard Library Search Algorithms)
45 0
|
25天前
|
Linux C++ iOS开发
【C++ 17 新特性 文件管理】探索C++ Filesystem库:文件和目录操作的全面指南(二)
【C++ 17 新特性 文件管理】探索C++ Filesystem库:文件和目录操作的全面指南
237 2
|
25天前
|
Linux API C++
【C++ 17 新特性 文件管理】探索C++ Filesystem库:文件和目录操作的全面指南(一)
【C++ 17 新特性 文件管理】探索C++ Filesystem库:文件和目录操作的全面指南
294 2
|
9天前
|
C++
glog --- C++日志库
glog --- C++日志库
|
17天前
|
XML JSON JavaScript
推荐一个比较好用的c++版本http协议库-cpp-httplib
推荐一个比较好用的c++版本http协议库-cpp-httplib
36 1
|
24天前
|
安全 网络性能优化 Android开发
深入解析:选择最佳C++ MQTT库的综合指南
深入解析:选择最佳C++ MQTT库的综合指南
81 0
|
24天前
|
XML 运维 监控
【深入探究 C++ 日志库清理策略】glog、log4cplus 和 spdlog 的日志文件管理策略
【深入探究 C++ 日志库清理策略】glog、log4cplus 和 spdlog 的日志文件管理策略
63 0
|
存储 算法 程序员
【C/C++ 线性表 简介】C/C++中的线性表探索:从标准库到自定义实现
【C/C++ 线性表 简介】C/C++中的线性表探索:从标准库到自定义实现
35 0