本文共 9402 字,大约阅读时间需要 31 分钟。
用qt的知道,qt有方便简单的信号槽机制,但需要专门的qt工具处理。
如果想直接使信号槽就可以使用sigslot库,或者sigc++库,或者boost中的signals,这里介绍sigslot和sigc++库。sigslot.h:只有一个头文件,使用简单方便。
sigc++:包含文件多,但功能更强大。#include "sigslot.h"
//在sigslot.h的420,将:typedef sender_set::const_iterator const_iterator; //改为:typedef typename sender_set::const_iterator const_iterator;
class mySg { sigc::signal0<> sg1; // 无参数 sigc::signal2sg2; // 2个参数 }
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);
sig.sg1.disconnect(&slt); sig.sg1.disconnect_all();
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; }
可以在下载已经编好的库文件,2.8.0版
注意1:在用高版本编译时,如2.8.0,可能会提示找不到msvc_recommended_pragmas.h,可以在vs的属性 -> C/C -> 高级 -> 强制包含文件
去掉msvc_recommended_pragmas.h,或者添加一个msvc_recommended_pragmas.h文件,在的源代码时已经放入了该文件。
注意2:在使用高版本(如2.9.7)编译时,若提示找不到slot.cc等文件,可以使用低版本中的放入相应位置即可。* 项目 -> VC++目录 -> 包含目录: 添加 sigc++所在的目录* 添加下列代码:
#include#ifdef _DEBUG #pragma comment(lib,"sigcd.lib") #else #pragma comment(lib,"sigc.lib") #endif
//返回值: int,2个参数:char*, double,参数个数可以直接指定 sigc::signalsg1; sigc::signal2 sg2; class mySg { sigc::signal2 sg3; }
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::signal2sg3; int on_func(char*, double)(){} }
ccSg1.disconnect(); ccSg2.disconnect();
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; }
转载地址:http://mmzdx.baihongyu.com/