简体   繁体   中英

C++ Boost signals and slots connection

I am trying to connect a gui to my logic thread using boosts signals and slots, the logic class has a neat method to connect functions to the signal. Here is a simplified replica of the locig class:

#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
}

Here is a simplified replica of the gui class

#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;

}

At some point in my code the gui class is already instantiated but the logic class isn't. So i want to instantiate the LogicClass and subscribe the GuiClass::draw_stuff(const double&) to the LogicClass::sig signal. Something like

#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;
}

This unfortunately doesn't work. Goes without saying it would like it to work very much!

I know Qt also implements signals & slots, but i would like to use boost for portability with other UI libraries.

Looks like you meant to bind draw_stuff instead of hardcoded doStuff inside of that register function:

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

And then

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

Simple Demo

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();
}

Prints

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM