How to check main event loop is running?
I need to perform some action with X11, to manage a window created with PyQt4. This action cannot be done before the event-loop has begun, and it has to be done asap after the window has been painted on the screen.
I managed to do this already by launching a QThread in my topmost widget's constructor. The QThread will keep polling until the window is hosted by X Window Manager, and then it performs the actions i need it to do.
However, i thought it'd be nicer to use event-handling rather than event-polling. So i would like my top-level QWidget to receive a signal as soon as the event-loop begins. I've understood that using postEvent() would be useful since the event will be released as soon as the event-loop will begin. But i am not sure yet as to how i should use that.
For now i call the postEvent in the main function like so:
@app = QtGui.QApplication(sys.argv)
widget = MyWidget()
# now i assume this should successfully post the event:
# i chose the ApplicationActive event, is it correct?
# then i connect the event to the widget:
widget, QtCore.SLOT('on_loop')) # the on_loop is my widget's callback
In the Widget definition, the callback is defined so:
@def on_loop(self, event): print 'event received is:', event@
Of course, it doesn't work, otherwise i wouldn't be here :)
I'm new to Qt4, not very familiar with signal-slot yet. Another idea i got was perhaps to send the event from my widget constructor, to itself. But i'm again unsure as to how i should implement that.
I'd like some guidance, thanks :)
I'm usually using QTimer::singleShot() to postpone actions until the event loop is running (and iddle;).
Yep, it's what i did, but with a QThread and a while loop. But i wanted to find a more secure way to do that.
First of all a event is not a signal. You can not connectec a Event with slot.
To intercept the event you need to reimplement the function:
'event (QEvent e) ' on your QWidget class. then you can check if the event received is the event which you have sent.
Another way to know when your widget was showed is re implement the function: showEvent (QShowEvent event ).
@Renato: the QShowEvent() is reveived before the window is actually hosted on X. I'll stick the QThread technique which works anyway. At least i've learnt something about event handling :) Thanks.
unclewerner is right, use the static method "QTimer::singleShot() ":http://doc.qt.nokia.com/4.7/qtimer.html#singleShot. Once it fires, it calls the slot given in the arguments:
Supposed (from your Python code), you want to call slot on_loop() in object widget once the event loop runs, add this code somewhere in your app:
QTimer::singleShot(0, widget, "on_loop");
This all works without threads and sending events manually.
@ unclewerner & @ Volker: you seem to prefer QTimer to QThread: is there any advantage using one or the other? is QTimer not a thread with a loop?
Timers are processed in the event loop, so the slot will be called once the event loop is running. No Threads needed.
[quote author="jesuisbenjamin" date="1307145093"]@ unclewerner & @ Volker: you seem to prefer QTimer to QThread: is there any advantage using one or the other? is QTimer not a thread with a loop?[/quote]
Why do it complicated, when there is a simple solution? You can easily shoot yourself into the foot with a QThread, but it's hard with a QTimer. I don't care about the actual implementation of QTimer's singleShot - it just works.
But if you prefer to implement a QThread based code with some 10s of lines, compared to a one liner... it's your choice.