Connecting to a signal in a contained instance
-
Hello everybody,
I can't find a more elegant way of connecting to a signal which is emitted by a class encapsulated inside another class that I am using, Here is the sample code:class Worker : public QObject { Q_OBJECT public: explicit Worker() : m_timer(this) {} virtual ~Worker(); private slots: void init() { connect(&m_timer, SIGNAL(timeout()), this, SLOT(onTimeout())); m_timer.start(100); } void onTimeout() { double v = 0; //if (condition) emit newValue(v); } void finish() { m_timer.stop(); emit finished(); } private: QTimer m_timer; signals: void newValue(double v); //the "hidden" signal void finished(); }; class ThreadContainer : public ThreadContainer { Q_OBJECT public: explicit ThreadContainer(QObject* parent = NULL) { worker = new Worker; t = new QThread(this); worker->moveToThread(t); connect(t, SIGNAL(started()), worker, SLOT(init())); connect(this, SIGNAL(sig_finish()), worker, SLOT(finish())); connect(worker, SIGNAL(finished()), t, SLOT(quit())); connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater())); connect(t, SIGNAL(finished()), t, SLOT(deleteLater())); t->start(); }; virtual ~ThreadContainer() { emit sig_finish(); t->quit(); t->wait(1000); }; const Worker* getWorker() {return const_cast<Worker*>(worker);}; signals: void newValue(double v); void sig_finish(); public slots: void slotNewValue(double v); private: QThread* t; Worker* worker; }; class window : public QMainWindow { Q_OBJECT public: window(QWidget *parent = 0) { ui.setupUi(this); connect(m_Container.getWorker(), SIGNAL(newValue(double)), this, SLOT(slotNewValue(double))); } ~window(){}; private slots: void slotNewValue(double v) { //display the new value ui.lbl->setText(QString("%1").arg(v)); } private: Ui::QtTestClass ui; ThreadContainer m_Container; protected: };
I would like to avoid calling "m_Container.getWorker()" to get the pointer to the instance emitting the signal.
Another way would be relaying the signal from the Worker class to ThreadContainer and then to my window class, but that's probably not efficient, either.
Any suggestions? -
Hi and welcome to devnet,
connecting a signal to another signal is supported and also a good practice when you want to hide the internal implementation of a composed object.
In you case you can connect the
Worker::newValue()
signal to theThreadContainer::newValue()
signal and the handle theThreadContainer::newValue()
signal in your MainWindow