用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;
}

信号槽库:sigslot.h和sigc++使用的更多相关文章

  1. QT——信号槽

    结合教程,写出如下关于信号槽的代码,将教程中信号槽两种方式写入同一个界面中. #include "mainwindow.h" #include <QApplication&g ...

  2. 信号和槽有一个非常精炼的C++实现,作者是Sarah Thompson,该实现只有一个头文件sigslot.h,跨平台且线程安全

    关于信号和槽有一个非常精炼的C++实现,作者是Sarah Thompson,该实现只有一个头文件sigslot.h,跨平台且线程安全. 源码在:http://sigslot.cvs.sourcefor ...

  3. Q_OBJECT提供了信号槽机制、国际化机、RTTI 的反射能力(cpp中使用Q_OBJECT导致无法处理moc,就需要#include “moc_xxx.h”)

     只有继承了QObject类的类,才具有信号槽的能力.所以,为了使用信号槽,必须继承QObject.凡是QObject类(不管是直接子类还是间接子类),都应该在第一行代码写上Q_OBJECT.不管是不 ...

  4. Boost信号/槽signals2

    信号槽是Qt框架中一个重要的部分,主要用来解耦一组互相协作的类,使用起来非常方便.项目中有同事引入了第三方的信号槽机制,其实Boost本身就有信号/槽,而且Boost的模块相对来说更稳定. signa ...

  5. QT 信号槽connect中解决自定义数据类型或数组作为函数参数的问题——QT qRegisterMetaType 注册MetaType——关键:注册自定义数据类型或QMap等容器类

    一般情况下信号槽直接连接方式不会出现问题,但是如果信号与槽在不同线程或Qt::QueuedConnection方式连接,可能会在连接期间报以下类似问题,如: QObject::connect: Can ...

  6. 非Qt工程使用Qt的信号槽机制

    非Qt工程,使用Qt的信号槽机制,蛋疼不?反正我现在就是要做这样一件蛋疼的事. 要使用Qt的信号槽机制,下面是从Qt Assist里面关于 signal & slots 的一句介绍: All ...

  7. Qt 跨UI线程的数据交换和信号-槽调用实现方案汇总

    一.目录 转载1: http://my.oschina.NET/fanhuazi/blog/737224?ref=myread 点击打开链接 转载2: http://www.qtcn.org/bbs/ ...

  8. Qt5中的信号槽

    Qt4中的信号槽 Qt4中的信号槽是通过SIGNAL,SLOT两个宏,将参数转换成字符串.Qt编译前,会从源码的头文件中提取由signal和slot声明的信号和槽的函数, 将其组成一张信号和槽对应的字 ...

  9. Pyqt 控件的信号槽事件定义方法

    转载来自:http://my.oschina.net/midnite/blog/39399 Qt采用信号槽来设定UI界面上元素动作的事件绑定.自Qt4.5开始,引入了一个新的信号槽与事件绑定的方法.界 ...

随机推荐

  1. CentOS网络设置 couldn't resolve host 'mirrorlist.centos.org问题解决

    在VMWare上安装好centos后,使用yum安装nodejs报错:can not resolve host 'mirritlist.centos.org', 百度上很多都说在/etc/resolv ...

  2. ClassNotFountException 与 NoClassDefineError

    一 知识准备 NoClassDefFoundError:正如它们的名字所说明的是一个错误 (Error),而ClassNotFoundException是一个异常.正如上一章节所说Exception和 ...

  3. 7 Vue.js实现loading1

    1 2 3 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/filter ...

  4. Android stadio 自定义debug release keystore

    1.添加siggnig name 随意,不过按我写的就可以了.设置完成之后,你的build.grade就会多出来一些: android { signingConfigs { signingConfig ...

  5. Idea中maven依赖图查看

    技术交流群: 233513714 使用Intellij idea,想看看它的maven依赖图,根据eclipse的经验,不是很容易能找到Intellij idea对应的功能.在打开的pom.xml文件 ...

  6. PowerDesigner如何将一个包里的表拷贝到另一个表以后在视图中也可以显示?

    第一步:选中PhysicalDiagram_1 第二步:点击:“ Symbol”按钮, 第三步:点击“Show Symbols”,出现如下界面 第四步:选中State.  

  7. 让NVelocity做更多的事,VS Extension+NVelocity系列

    我不知道园子里到底有多少人喜欢使用NVelocity这个模板引擎,其实说实话,如果现在让我选,我对Razor的喜好要比NVelocity或者T4等等的模板引擎更多一些,当然了,个人看法而已.只是我在公 ...

  8. 【Text Justification】cpp

    题目: Given an array of words and a length L, format the text such that each line has exactly L charac ...

  9. 使用 JsonPath 完成接口自动化测试中参数关联和数据验证(Python语言)

    背景: 接口自动化测试实现简单.成本较低.收益较高,越来越受到企业重视 restful风格的api设计大行其道 json成为主流的轻量级数据交换格式 痛点: 接口关联 也称为关联参数.在应用业务接口中 ...

  10. 以太访solidity常用的函数有哪些

    以太坊:什么是ERC20标准? 不以规矩,不能成方圆 许多人应该都听过 代码即法律(Code Is Law),因为程序写完了,无论执行多少次都会得到同样的结果,除非有外界因素的干扰.在多人协作的过程中 ...