This doesn't make sense to me.
Signals are sent to objects (regardless of being a child item), not child items of a parent.
But what are you trying to do? Maybe there's a better way to do what you want.
This doesn't make sense to me.
Signals are sent to objects (regardless of being a child item), not child items of a parent.
But what are you trying to do? Maybe there's a better way to do what you want.
boblatino (23rd July 2010)
This sort of thing? Two independent windows counting when they receive signals, and continuing even when you minimise or close either.
Qt Code:
#include <QtGui> #include <QDebug> { Q_OBJECT public: count = 0; setCentralWidget(central); } public slots: void receive() { } private: QLabel *central; int count; }; Q_OBJECT public: m_winA = new Window(); m_winA->setWindowTitle("Window A"); connect(this, SIGNAL(signalA()), m_winA, SLOT(receive())); m_winB = new Window(); m_winB->setWindowTitle("Window B"); connect(this, SIGNAL(signalB()), m_winB, SLOT(receive())); m_winA->show(); m_winB->show(); // some fake incoming events m_count = 0; connect(&m_timer, SIGNAL(timeout()), this, SLOT(incoming())); m_timer.start(100); } ~Controller() { delete m_winA; delete m_winB; } public slots: void incoming() { if (m_count++ % 3 == 0) emit signalA(); else emit signalB(); } signals: void signalA(); void signalB(); private: Window *m_winA; Window *m_winB; int m_count; QTimer m_timer; }; int main(int argc, char *argv[]) { Controller c; return app.exec(); } #include "main.moc"To copy to clipboard, switch view to plain text mode
boblatino (23rd July 2010)
Yes, Exactly like that. The problem is that when one of the mainWindows is shown, the timer (or any event in the controller) justs emits the signal correctly, but the other window did not receive it until the one that is currently shown is closed (via the X in the window). The controller is a QObject and the windows are QWidgets so the controller cant be the parent of both windows. In fact they are parentless. Is there any way to put both windows a parent? Is this the correct way of doing this? Can both windows be parentless without affecting Qt way to dispatch events?
Thanks
Ramiro
I have modified a little bit the example, but is almost the same. It will show / hide one or the other QWidget
Qt Code:
#include <QtGui> #include <QDebug> { Q_OBJECT public: setCentralWidget(central); } public slots: void show() { this->show(); } void hide() { this->hide(); } private: QLabel *central; }; Q_OBJECT public: m_winA = new Window(); m_winA->setWindowTitle("Window A"); connect(this, SIGNAL(signalA()), m_winA, SLOT(show())); connect(this, SIGNAL(signalA2()), m_winA, SLOT(hide())); m_winB = new Window(); m_winB->setWindowTitle("Window B"); connect(this, SIGNAL(signalB()), m_winB, SLOT(show())); connect(this, SIGNAL(signalB2()), m_winB, SLOT(hide())); // some fake incoming events m_count = 0; connect(&m_timer, SIGNAL(timeout()), this, SLOT(incoming())); m_timer.start(100); } ~Controller() { delete m_winA; delete m_winB; } public slots: void incoming() { //Just show one and hide the other with signals. //The signals are emited but it will not arrive to //the slot until the other window is hidden. if (m_count++ % 3 == 0) { emit signalA(); emit signalB2(); } else { emit signalB(); emit signalA(); } } signals: void signalA(); void signalB(); private: Window *m_winA; Window *m_winB; int m_count; QTimer m_timer; }; int main(int argc, char *argv[]) { Controller c; return app.exec(); } #include "main.moc"To copy to clipboard, switch view to plain text mode
Thanks
Ramiro
Hi,
Why are you using singals and slots? You have access to "m_winA" and "m_winB" pointers that can be used directly:
Qt Code:
public slots: void incoming() { if ((m_count++ % 3) == 0) { m_winA->show(); m_winB->hide(); } else { m_winA->hide(); m_winB->show(); } }To copy to clipboard, switch view to plain text mode
Òscar Llarch i Galán
boblatino (23rd July 2010)
Yes, I know that. Its just to depict a simpler case. In my Controller class I have a separate thread that is calling the emit. So the reason to do it is for Qt to process the events in its graphical thread. If I call it directly, QT throws invalid thread exception.
Thanks
Ramiro
The QMainWindow class already has a show() and hide() slot inherited from QWidget that you are overriding. Each of your new slots calls itself in an infinite loop, which is why things go awry here.
You should either
- connect to the pre-existing slots by not defining a new show() and hide(),
- give your show() and hide() slot different names (or one slot with a parameter), or
- make sure your overrides also call QWidget::show() or hide().
This last option still was Not Quite Rightâ„¢ for me.Qt Code:
public slots: void show() { qDebug() << windowTitle() << "show()"; } void hide() { qDebug() << windowTitle() << "hide()"; }To copy to clipboard, switch view to plain text mode
boblatino (24th July 2010)
Thanks ChrisW67, that names (show / hide) where just to ilustrate the 2 slots, but they have different names in the real application (sorry for my error, I did not take so much care with the names in the example). Im just seaking a valid way to do this (2 qwidgets parentless) or some other way to do it. I need an advice on this matter. Thanks a lot to all of the forum. Its realy a big help.
Thanks
Ramiro
I don't know what the problem is then. The two top-level windows in the example below hide/show just fine here (if both are hidden simultaneously the example app closes) and their timers are clearly running while hidden.
Qt Code:
#include <QtGui> #include <QDebug> { Q_OBJECT public: m_count = 0; setCentralWidget(central); connect(m_timer, SIGNAL(timeout()), this, SLOT(tick())); m_timer->start(100); } public slots: void tick() { central->display(m_count++); } private: QLCDNumber *central; QTimer *m_timer; int m_count; }; Q_OBJECT public: m_winA = new Window(); m_winA->setWindowTitle("Window A"); m_winA->move(0,0); m_winB = new Window(); m_winB->setWindowTitle("Window B"); m_winB->move(200,200); connect(this, SIGNAL(signalA()), m_winA, SLOT(show())); connect(this, SIGNAL(signalA()), m_winB, SLOT(hide())); connect(this, SIGNAL(signalB()), m_winA, SLOT(hide())); connect(this, SIGNAL(signalB()), m_winB, SLOT(show())); m_winA->show(); m_winB->show(); // some fake incoming events m_count = 0; connect(m_timer, SIGNAL(timeout()), this, SLOT(incoming())); m_timer->start(5000); } ~Controller() { delete m_winA; delete m_winB; } public slots: void incoming() { if (m_count++ % 2 == 0) emit signalA(); else emit signalB(); } signals: void signalA(); void signalB(); private: Window *m_winA; Window *m_winB; int m_count; QTimer *m_timer; }; int main(int argc, char *argv[]) { Controller c; return app.exec(); } #include "main.moc"To copy to clipboard, switch view to plain text mode
So, could be a problem that a different thread is calling the emit function? Or it just post an event to the Qt GUI thread? In the example above, the timer uses the same thread as the graphical thread.
Thanks
Ramiro
If the signals are cross-thread then they will be queued rather than the slot executing synchronously. Making the connections at line 37-41 Qt::QueuedConnection as they would be in the threaded scenario does not affect the performance. Perhaps you could produce a small example that more closely matches what you are doing.
boblatino (24th July 2010)
Hi ChrisW67, Im using a plain connect so it should be detected and working as a queued connect as shows in the documentation. The next I will do is force a Qt::QueuedConnection instead of relaing in Qt::AutoConnection. On monday I will have a pc with visual studio and I will create an example. Its basicaly the same as the above message, but instead of a QTimer that emits the signals, is a plain OS thread. The thread just dequeues elements and calls emit. Does you see an issue to have 2 widgets parentless that interact? Is this the correct way to doit?
Thanks
Ramiro
Could you prepare a minimal compilable example reproducing the problem?
Hi tbscope, I agree that signal / slot mechanism should be independant of child / parent, but why the Qt thread just doesnt process events for the non visible qwidget? Maybe Im doing something wrong. Is there any other way to do what Im trying to do? All the examples I have found, suppose that you have a main window and all the widgets are parented to it. No one is making 2 main windows parentless. Maybe there is another way to doit.
Thanks
Ramiro
Bookmarks