C++ 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 для переносимости с другими библиотеками пользовательского интерфейса.

1 ответ

Похоже, вы хотели связать draw_stuff вместо жестко закодированных doStuff внутри этой функции регистра:

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

А потом

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

Простая демонстрация

Жить на Колиру

#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)
Другие вопросы по тегам