C++语言之信号槽库:sigslot.h和sigc++使用
小标 2018-07-20 来源 : 阅读 2743 评论 0

摘要:本文主要向大家介绍了C++语言之信号槽库:sigslot.h和sigc++使用,通过具体的内容向大家展示,希望对大家学习C++语言有所帮助。

本文主要向大家介绍了C++语言之信号槽库:sigslot.h和sigc++使用,通过具体的内容向大家展示,希望对大家学习C++语言有所帮助。

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

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

 

sigslot库

官方地址

//sigslot.sourceforge.net/

在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:

    signal2moveBy;

    signal2resize;

    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++库

官方地址

//libsigc.sourceforge.net/

编译

下载已经编好的库文件,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等文件,可以使用低版本中的放入相应位置即可。

在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::signal2resize;     // 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::signal1printSS;

    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;

}


本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言C/C+频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 2 不喜欢 | 0
看完这篇文章有何感觉?已经有2人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程