C ++ Boost信号和插槽连接

时间:2018-02-05 14:31:57

标签: c++ boost boost-signals2

我正在尝试使用boost信号和插槽将gui连接到我的逻辑线程,逻辑类有一个简洁的方法将函数连接到信号。   这是locig类的简化副本:

#include <boost/signals2.hpp>
#include <boost/function.hpp>

typedef boost::signals2::signal<void (const double&)> some_signal;
typedef some_signal::slot_type some_slot;

class LogicClass {

  some_signal sig;

public:
  LogicClass();
  ~LogicClass();

  void register_callback(boost::function<void (const double&)>) {
    sig.connect(boost::bind(&LogicClass::doStuff(), this, _1));
  }
  void doStuff(); // Does a bunch of stuff in a separate thread and fires LogicClass::sig every now and then
}

这是gui类的简化副本

#include <boost/signals2.hpp>
#include <QWidget.h>

class GuiClass : public QWidget {
  Q_OBJECT //etc. etc. w.r.t. Qt stuff

public:
  GuiClass ();
  ~GuiClass ();

  void draw_stuff(const double&); // Want this to listen to LogicClass::sig;

}

在我的代码中的某些时候,gui类已经被实例化,但逻辑类却没有。所以我想实例化LogicClass并订阅GuiClass::draw_stuff(const double&)LogicClass::sig信号。像

这样的东西
#include <logicclass.h>
#include <guiclass.h>

GuiClass *gui; //Was initialized elsewhere, but available here;

void some_function() { 
  LogicClass *logic = new LogicClass();
  logic->register_callback(gui->drawStuff);
  logic->do_stuff(); //Start drawing on the gui
  delete logic;
}

遗憾的是,这不起作用。不言而喻,它希望它非常有效!

我知道Qt还实现了信号和功能。插槽,但我想使用boost来提高与其他UI库的可移植性。

1 个答案:

答案 0 :(得分:0)

看起来您打算在该注册函数中绑定draw_stuff而不是硬编码的doStuff

logic->register_callback(boost::bind(&GuiClass::draw_stuff, gui, _1));

然后

void register_callback(boost::function<void(double)> handler) {
    sig.connect(handler);
}

简单演示

<强> Live On Coliru

#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/signals2.hpp>

#include <boost/thread.hpp>
#include <iostream>

typedef boost::signals2::signal<void(double)> some_signal;
typedef some_signal::slot_type some_slot;

class LogicClass {
    some_signal sig;

  public:
    LogicClass() = default;
    ~LogicClass() = default;

    void register_callback(boost::function<void(double)> handler) {
        sig.connect(handler);
    }

    void doStuff() {
        std::cout << __PRETTY_FUNCTION__ << "\n";
        // Does a bunch of stuff in a separate thread and fires LogicClass::sig every now and then

        boost::thread([this] {
            for (double d : {1,2,3}) {
                boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
                sig(d);
            }
        }).join();
    }
};

#define Q_OBJECT
struct QWidget {};

class GuiClass : public QWidget {
    Q_OBJECT // etc. etc. w.r.t. Qt stuff

  public:
    GuiClass() = default;
    ~GuiClass() = default;

    void draw_stuff(double v) { std::cout << __PRETTY_FUNCTION__ << "(" << v << ")\n"; }
};

//#include <logicclass.h>
//#include <guiclass.h>

GuiClass *gui; // Was initialized elsewhere, but available here;

void some_function() {
    LogicClass *logic = new LogicClass();
    logic->register_callback(boost::bind(&GuiClass::draw_stuff, gui, _1));
    logic->doStuff(); // Start drawing on the gui
    delete logic;
}

int main() {
    GuiClass gui_instance;
    gui = &gui_instance;

    some_function();
}

打印

void LogicClass::doStuff()
void GuiClass::draw_stuff(double)(1)
void GuiClass::draw_stuff(double)(2)
void GuiClass::draw_stuff(double)(3)