C++ Boost 信号和槽连接

标签 c++ boost boost-signals2

我正在尝试使用 boost 信号和插槽将图形用户界面连接到我的逻辑线程,逻辑类有一个巧妙的方法将函数连接到信号。 这是 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 库的可移植性。

最佳答案

看起来你的意思是绑定(bind) 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)

关于C++ Boost 信号和槽连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48624854/

相关文章:

c++ - 错误 : ‘template’ (as a disambiguator) is only allowed within templates

c++ - 用 C++11 信号替换 boost-signals2

c++ - `` const Mat* 样本 `` param in OpenCV' s `` calcCovarMatrix`` 函数的工作原理?

c++ - 调试 MMC(非托管 C++)?

填充 vector 的 C++ 有状态仿函数

c++ - 用 boost spirit 解析一对整数

c++ - 将返回值转换为模板类型

c++ - 在哪里定义编译时常量?

c++ - 部分特化模板作为特征成员类型