Here is an example:
Qt Code:
{ Q_OBJECT public: { } public slots: void showMe() { show(); } void hideMe() { hide(); } }; { Q_OBJECT public: consumerThread(fifo<int> & f):f(f) { start(); } void run() { while(true) { int a; f.pop(a); if(a == 0) { emit showMe1(); emit hideMe1(); } else { emit showMe2(); emit hideMe2(); } } } signals: void showMe1(); void showMe2(); void hideMe1(); void hideMe2(); private: fifo<int> & f; }; { public: producerThread(fifo<int> & f):f(f) { start(); } void run() { while(true) { f.push(0); Sleep(1000); f.push(1); Sleep(1000); } } private: fifo<int> & f; }; { Q_OBJECT public: dispatcher() { consumerThread* consumer = new consumerThread(queue); producerThread* producer = new producerThread(queue); window1 = new window(); window2 = new window(); connect(consumer, SIGNAL(showMe1()), window1, SLOT(showMe())); connect(consumer, SIGNAL(showMe2()), window2, SLOT(showMe())); connect(consumer, SIGNAL(hideMe1()), window1, SLOT(hideMe())); connect(consumer, SIGNAL(hideMe2()), window2, SLOT(hideMe())); } private: fifo<int> queue; window* window1; window* window2; };To copy to clipboard, switch view to plain text mode
Thanks
Ramiro
Starting a thread in its constructor is in general a bad idea. But back to the main issue... you are aware that slots of a QThread subclass are executed in the context of the main thread and not the thread controlled by the QThread object, right? Please also explain what is the point in emitting showMe1() and immediately after that emitting hideMe1().
It could be simpler to explain what effect you want to achieve and we will suggest a better approach.
No, I didnt know that, but in the real code the thread is a OS thread (via CreateThread).
It has no point sorry. It should bePlease also explain what is the point in emitting showMe1() and immediately after that emitting hideMe1()
Qt Code:
emit showMe1(); emit hideMe2();To copy to clipboard, switch view to plain text mode
The idea is an application that has more than 1 top level window and a dispatcher that controls which window is shown. Sometimes it could be no window shown and sometimes 2 at the same time. The issue that we are facing now is that when a widget is hidden and other is put in the front (show), the first time you touch the window (we are using touchscreen), the event is processed by the hidden widget. The second time, the shown widget captures the event normaly. I have called activateWindow also but with no luck. Is there a better approach on this? I dont want to create and close (destroy) the widgets all the time so I have created them once and show / hide accordly. If I create them and destroy every time I dont have this problem.
Thanks
Ramiro
I don't think we can help you if you show us code that does something different than the one you are actually using...
If the two windows are never shown together maybe you should use a QStackedWidget instead of two widgets?
Anyway... if I wanted to have a mechanism for switching windows, I'd do it more or less like this:
Qt Code:
Q_OBJECT public: m_windows << win; if(m_current == -1) { setWindow(0); } } public slots: void next() { setWindow(m_current+1 % m_windows.count()); } void prev() { setWindow(m_current-1 % m_windows.count()); } void setWindow(int which) { if(m_current == which) return; if(m_current!=-1) { m_windows.at(m_current)->hide(); } m_current = which; m_windows.at(m_current)->show(); qApp->processEvents(); // optionally force event processing (don't unless sure it's required) } private: QList<QWidget *> m_windows; int current = -1; };To copy to clipboard, switch view to plain text mode
Then it's just a matter of connecting a signal to one of the slots defined in the dispatcher.
boblatino (26th July 2010)
Thanks wysota, so that will be another way of show / hide the windows, but why the inactive window (hidden) takes the focus instead of the one that is shown the first time? After just a click the shown window it will regain focus and work. I have also called activateWindow but it doesnt take the control of the focus. Also I dont understand why a hidden window can take the user event of a press.
Thanks
Ramiro
when you have QueuedConnection emit post event. that event must be processed by event loop in concrete widget; because only one parentless widet wokrs with main event loop at same time(the signal is posted but nobody cares, because main event loop processing another widget's events) you should create event loops for both threads.
OR
you should inherit from QDialog and use exec(); instead show(); because exec creates own dialog's event loop.
Last edited by GreenScape; 27th July 2010 at 00:38.
no, u just should to create event loop for each widget.
example:
create 2 threads, inside each thread create widget, and event loop.
this will look like 2 applications, each widget in its own thread, but in fact it will be one app
Last edited by GreenScape; 27th July 2010 at 00:45.
I also have the same idea, only one thread should be the graphical thread. So how can I solve the problem:
Thanksinactive window (hidden) takes the focus instead of the one that is shown the first time? After just a click the shown window it will regain focus and work.
Ramiro
First determine what exactly happens. It could be you are not letting the events be processed and something doesn't know it should release (or gain) focus, i.e. you can't have a focus on a widget which is hidden, so if you do:
it will probably not work but this might:Qt Code:
widget->show(); widget->setFocus(Qt::OtherFocusReason);To copy to clipboard, switch view to plain text mode
Qt Code:
widget->show(); widget->setFocus(Qt::OtherFocusReason);To copy to clipboard, switch view to plain text mode
boblatino (27th July 2010)
Bookmarks