信号槽库:sigslot.h和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;
}
信号槽库:sigslot.h和sigc++使用的更多相关文章
- QT——信号槽
结合教程,写出如下关于信号槽的代码,将教程中信号槽两种方式写入同一个界面中. #include "mainwindow.h" #include <QApplication&g ...
- 信号和槽有一个非常精炼的C++实现,作者是Sarah Thompson,该实现只有一个头文件sigslot.h,跨平台且线程安全
关于信号和槽有一个非常精炼的C++实现,作者是Sarah Thompson,该实现只有一个头文件sigslot.h,跨平台且线程安全. 源码在:http://sigslot.cvs.sourcefor ...
- Q_OBJECT提供了信号槽机制、国际化机、RTTI 的反射能力(cpp中使用Q_OBJECT导致无法处理moc,就需要#include “moc_xxx.h”)
只有继承了QObject类的类,才具有信号槽的能力.所以,为了使用信号槽,必须继承QObject.凡是QObject类(不管是直接子类还是间接子类),都应该在第一行代码写上Q_OBJECT.不管是不 ...
- Boost信号/槽signals2
信号槽是Qt框架中一个重要的部分,主要用来解耦一组互相协作的类,使用起来非常方便.项目中有同事引入了第三方的信号槽机制,其实Boost本身就有信号/槽,而且Boost的模块相对来说更稳定. signa ...
- QT 信号槽connect中解决自定义数据类型或数组作为函数参数的问题——QT qRegisterMetaType 注册MetaType——关键:注册自定义数据类型或QMap等容器类
一般情况下信号槽直接连接方式不会出现问题,但是如果信号与槽在不同线程或Qt::QueuedConnection方式连接,可能会在连接期间报以下类似问题,如: QObject::connect: Can ...
- 非Qt工程使用Qt的信号槽机制
非Qt工程,使用Qt的信号槽机制,蛋疼不?反正我现在就是要做这样一件蛋疼的事. 要使用Qt的信号槽机制,下面是从Qt Assist里面关于 signal & slots 的一句介绍: All ...
- Qt 跨UI线程的数据交换和信号-槽调用实现方案汇总
一.目录 转载1: http://my.oschina.NET/fanhuazi/blog/737224?ref=myread 点击打开链接 转载2: http://www.qtcn.org/bbs/ ...
- Qt5中的信号槽
Qt4中的信号槽 Qt4中的信号槽是通过SIGNAL,SLOT两个宏,将参数转换成字符串.Qt编译前,会从源码的头文件中提取由signal和slot声明的信号和槽的函数, 将其组成一张信号和槽对应的字 ...
- Pyqt 控件的信号槽事件定义方法
转载来自:http://my.oschina.net/midnite/blog/39399 Qt采用信号槽来设定UI界面上元素动作的事件绑定.自Qt4.5开始,引入了一个新的信号槽与事件绑定的方法.界 ...
随机推荐
- CentOS网络设置 couldn't resolve host 'mirrorlist.centos.org问题解决
在VMWare上安装好centos后,使用yum安装nodejs报错:can not resolve host 'mirritlist.centos.org', 百度上很多都说在/etc/resolv ...
- ClassNotFountException 与 NoClassDefineError
一 知识准备 NoClassDefFoundError:正如它们的名字所说明的是一个错误 (Error),而ClassNotFoundException是一个异常.正如上一章节所说Exception和 ...
- 7 Vue.js实现loading1
1 2 3 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/filter ...
- Android stadio 自定义debug release keystore
1.添加siggnig name 随意,不过按我写的就可以了.设置完成之后,你的build.grade就会多出来一些: android { signingConfigs { signingConfig ...
- Idea中maven依赖图查看
技术交流群: 233513714 使用Intellij idea,想看看它的maven依赖图,根据eclipse的经验,不是很容易能找到Intellij idea对应的功能.在打开的pom.xml文件 ...
- PowerDesigner如何将一个包里的表拷贝到另一个表以后在视图中也可以显示?
第一步:选中PhysicalDiagram_1 第二步:点击:“ Symbol”按钮, 第三步:点击“Show Symbols”,出现如下界面 第四步:选中State.
- 让NVelocity做更多的事,VS Extension+NVelocity系列
我不知道园子里到底有多少人喜欢使用NVelocity这个模板引擎,其实说实话,如果现在让我选,我对Razor的喜好要比NVelocity或者T4等等的模板引擎更多一些,当然了,个人看法而已.只是我在公 ...
- 【Text Justification】cpp
题目: Given an array of words and a length L, format the text such that each line has exactly L charac ...
- 使用 JsonPath 完成接口自动化测试中参数关联和数据验证(Python语言)
背景: 接口自动化测试实现简单.成本较低.收益较高,越来越受到企业重视 restful风格的api设计大行其道 json成为主流的轻量级数据交换格式 痛点: 接口关联 也称为关联参数.在应用业务接口中 ...
- 以太访solidity常用的函数有哪些
以太坊:什么是ERC20标准? 不以规矩,不能成方圆 许多人应该都听过 代码即法律(Code Is Law),因为程序写完了,无论执行多少次都会得到同样的结果,除非有外界因素的干扰.在多人协作的过程中 ...