信号槽库:sigslot.h和sigc++使用
程序员文章站
2022-03-09 21:33:33
用qt的知道,qt有方便简单的信号槽机制,但需要专门的qt工具处理。
如果想直接使信号槽就可以使用sigslot库,或者sigc++库,或者boost中的signals,这里介绍sigslot和si...
用qt的知道,qt有方便简单的信号槽机制,但需要专门的qt工具处理。
如果想直接使信号槽就可以使用sigslot库,或者sigc++库,或者boost中的signals,这里介绍sigslot和sigc++库。
sigslot.h:只有一个头文件,使用简单方便。
sigc++:包含文件多,但功能更强大。
sigslot库
官方地址
在vs2013中使用
包含头文件#include "sigslot.h"改动:
//在sigslot.h的420,将: typedef sender_set::const_iterator const_iterator; //改为: typedef typename sender_set::const_iterator const_iterator;
基本使用:
signal0~signal8:信号类:作为类成员class mysg { sigc::signal0<> sg1; // 无参数 sigc::signal2 sg2; // 2个参数 }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);disconnection
解除连接:可以使用disconnect()和disconnect_all()
sig.sg1.disconnect(&slt); sig.sg1.disconnect_all();emiting
发送信号:可以直接使用()运算符,也可以调用signal的emit函数
sig.sg1.emit(); sig.sg2("str",0.1);
实例:
#include #include #include #include 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 moveby; signal2 resize; signal1 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; }
sigc++库
官方地址
编译
下载已经编好的库文件,2.8.0版
注意1:在用高版本编译时,如2.8.0,可能会提示找不到ms_recommended_pragmas.h,可以在vs的
属性 -> c/c -> 高级 -> 强制包含文件
去掉msvc_recommended_pragmas.h,或者添加一个msvc_recommended_pragmas.h文件,
注意2:在使用高版本(如2.9.7)编译时,若提示找不到slot.cc等文件,可以使用低版本中的放入相应位置即可。
在vs中使用
* 项目 -> vc++目录 -> 包含目录: 添加 sigc++所在的目录 * 添加下列代码:
#include #ifdef _debug #pragma comment(lib,"sigcd.lib") #else #pragma comment(lib,"sigc.lib") #endif
基本使用:
signal
信号类:可以作为其它类成员,也可直接定义
//返回值: int,2个参数:char*, double,参数个数可以直接指定 sigc::signal sg1; sigc::signal2 sg2; class mysg { sigc::signal2 sg3; }
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 sg3; int on_func(char*, double)(){} }
disconnection
如果不需要解连接,可以不用定义sigc::connection
ccsg1.disconnect(); ccsg2.disconnect();
emiting
// 发送信号:调用signal的emit函数
sg1.emit("str",0.1); sg2.emit("str",0.1);
实例:
#include #include #include #include using namespace std; #include #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 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 moveby; sigc::signal2 resize; // return void type, and 2 parameters sigc::signal 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 printss; sigc::connection ccprintss = printss.connect(sigc::ptr_fun1(&printspacestr)); //ccprintss.disconnect(); sigc::signal0 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; }
上一篇: 仿IOS 带字母索引的滑轮控件
下一篇: 实战引流思维分享:打造一套引流推广体系