Qt Framework Events Signals Threads


Published on

Qt Framework Events Signals Threads

Published in: Technology, Education
1 Like
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Qt Framework Events Signals Threads

  1. 1. Threads, Events, Signals/Slots<br />Multithreaded Programming in QT <br />
  2. 2. Content<br />Threading in QT<br />QT Reentrancy vs QT ThreadSafe<br />GUI and Non-GUI Threads<br />Events and Event Loop<br />Mechanism, restriction of using Events<br />Integration in S60<br />Signals and Slots<br />API and usage<br />Implementation details<br />
  3. 3. Threading in QT<br />QT framework provide APIs “similar” to Posix<br />Base class is QThread, derive a class from this and implement run()<br />Important thread APIs are<br />QThread::Run() – Starting point of thread, virtual function to be overridden by Apps<br />QThread::Start() – Begins execution of thread by calling run()<br />QThread::Stop() – For terminating thread<br />QThread::Wait() – For waiting for thread completion<br />Objects in QT are associated with the thread they are created in<br />There is an API to transfer the Ownership of on Object from one thread to another<br />Imp: Ownership of QThread is with thread which created the object, typically Main Thread.<br />Typical thread will create an Object associated to the thread in Run() and start event loop by calling QThread::exec()<br />
  4. 4. Threading in QT contd..<br />QT Reentrant methods<br />Methods of class can be called simultaneously by different threads as long as they are invoked on different objects<br />That is reentrant methods do not operate on global or static data<br />However these methods are not atomic and hence not thread safe if invoked on same object<br />QT Thread safe methods<br />A thread-safe function can be called simultaneously from multiple threads, even when the invocations use shared data, because all references to the shared data are serialized<br />Higher degree of guarantee <br />These methods are reentrant and atomic<br />QT provide Thread safe synchronization APIs<br />Like QMutex , Qsemaphore etc.. (More on Next slide)<br />Using these user application can make explicitly make reentrant API thread safe<br />
  5. 5. Threading in QT contd..<br />Qtprovides all Posix compatible Synchronization APIs<br />Like mutex, semaphore, readers writers lock, conditional variables<br />Qtincludes the following thread classes:<br />QThreadprovides the means to start a new thread.<br />QThreadStorageprovides per-thread data storage.<br />QMutexprovides a mutual exclusion lock, or mutex.<br />QMutexLockeris a convenience class that automatically locks and unlocks a QMutex.<br />QReadWriteLockprovides a lock that allows simultaneous read access.<br />QReadLockerand QWriteLocker are convenience classes that automatically lock and unlock a QReadWriteLock.<br />QSemaphoreprovides an integer semaphore (a generalization of a mutex).<br />QWaitConditionprovides a way for threads to go to sleep until woken up by another thread.<br />
  6. 6. Threading in QT contd..<br />In QT UI operations are allowed only from Main UI thread<br />QCoreApplication::exec() should be called from main thread<br />QWidget and all its subclasses, are not reentrant. They can only be used from the main thread. Objects of Classes derived from QWidget can only be created in Main UI thread<br />Similar restrictions are there in S60 also RWindow handle and API using RWindow handle can be accessed from main UI thread only<br />
  7. 7. Events and Event Loop in QT <br />QT is designed as an Event based non preemptive scheduling model<br />Each thread executes an event loop<br />Main UI thread execute Application event loop (Q[core]Application::exec)<br />Auxiliary Threads execute thread specific event loop (QThread::exec())<br />Event are targeted towards specific QObjects and handled by event handlers<br />Event handlers run till completion for event loop<br />QT QObject implements composite pattern<br />That is QObjects can have a parent and a collection of children<br />Events are propagated to parents if no handled by child<br />Child can ignore events by ignore() method or can accept() and stop propagation<br />
  8. 8. Events and Event Loop in QT contd..<br />QT guarantees that an Object will receive events in its own thread <br />A QObject can “SendEvent()” synchronously to the objects of its own thread, i.eSendEvent() can be used for Intra thread communication only<br />QObject can “postEvent()” asynchronously to objects in other thread<br />QObject can ensure all posted event of on Object are delivered synchronously using “SendPostedEvent()” this again can be done for Objects of its own thread<br />QT Events<br />System events For Windowing system, Key events , Mouse events<br />Some of these events collate e.g. Multiple Paint events in the Queue are collated and delivered as single Paint event with union of all dirty regions.<br />Application can define its own Custom events<br />Events can be prioritized<br />
  9. 9. Events and Event Loop in QT contd..<br />Qtoffers five levels at which events can be processed and filtered:<br />We can reimplement a specific event handler<br />Reimplementingevent handlers such as mousePressEvent(), keyPressEvent(), and paintEvent() is by far the most common way to process events. We have already seen many examples of this.<br />We can reimplementQObject::event()<br />By reimplementing the event() function, we can process events before they reach the specific event handlers. This approach is mostly needed to override the default meaning of the Tab key, as shown earlier (p. 168). This is also used to handle rare types of events for which no specific event handler exists (e.g., QEvent::HoverEnter). When we reimplement event(), we must call the base class&apos;s event() function for handling the cases we don&apos;t explicitly handle.<br />We can install an event filter on a single QObject.<br />Once an object has been registered using installEventFilter(), all the events for the target object are first sent to the monitoring object&apos;s eventFilter() function. If multiple event filters are installed on the same object, the filters are activated in turn, from the most recently installed back to the first installed.<br />We can install an event filter on the QApplication object.<br />Once an event filter has been registered for qApp (the unique QApplication object), every event for every object in the application is sent to the eventFilter() function before it is sent to any other event filter. This approach is mostly useful for debugging. It can also be used to handle mouse events sent to disabled widgets, which QApplication normally discards.<br />We can subclass QApplication and reimplement notify().<br />Qtcalls QApplication::notify() to send out an event. Reimplementing this function is the only way to get all the events, before any event filters get the opportunity to look at them. Event filters are generally more useful, because there can be any number of concurrent event filters, but only one notify() function.<br />
  10. 10. Signals and Slots<br />Unique inter-object communication mechanism, provides<br />Type-safe callback between objects<br />The signature of a signal must match the signature of the receiving slot. (In fact a slot may have a shorter signature than the signal it receives because it can ignore extra arguments.)<br />Facilitates loose coupling / encapsulation<br />Sender and receiver does not ”know about” each other<br />1-to-many, many-to-1 communication between objects<br />Fully Object-oriented<br />Signals: emit events<br />declare as signals, otherwise normal member functions<br />You don&apos;t implement them. Rather, you send them with the keyword emit<br />E.g. emit sliderChanged(5)<br />Slots: receive and handle events<br />Normal member functions declared as slots<br />Connect: must connect signals to slots<br />QObject::connect( mymenu, SIGNAL(activated(int)), myobject, SLOT(slotDoMenuFunction(int)) );<br />
  11. 11. Signals and Slots Contd..<br />New C++ Syntax for defining Signals/Slots<br />class myClass : public QObject {<br />Q_OBJECT //required macro, no semicolon<br />…<br />signals: <br /> void somethingHappened();<br />… <br />public slots: <br /> void slotDoSomething();<br />…<br />private slots:<br /> void slotDoSomethingInternal();<br />…<br />};<br />moc: meta object compiler (preprocessor) converts these new keywords to real C++<br />
  12. 12. Signals and Slots contd..<br />One signal can be connected to many slots:<br />connect(slider, SIGNAL(valueChanged(int)), spinBox, SLOT(setValue(int))); <br />connect(slider, SIGNAL(valueChanged(int)), this, SLOT(updateStatusBarIndicator(int)));<br />When the signal is emitted, the slots are called one after the other, in an unspecified order.<br />Many signals can be connected to the same slot:<br />connect(lcd, SIGNAL(overflow()), this, SLOT(handleMathError())); <br />connect(calculator, SIGNAL(divisionByZero()), this, SLOT(handleMathError()));<br />When either signal is emitted, the slot is called.<br />A signal can be connected to another signal:<br />connect(lineEdit, SIGNAL(textChanged(constQString &)), this, SIGNAL(updateRecord(constQString &)));<br />When the first signal is emitted, the second signal is emitted as well. Apart from that, signal–signal connections are indistinguishable from signal–slot connections.<br />Connections can be removed:<br />disconnect(lcd, SIGNAL(overflow()), this, SLOT(handleMathError()));<br />This is rarely needed, because Qt automatically removes all connections involving an object when that object is deleted.<br />
  13. 13. Signals and Slots Contd..<br />Qt supports four types of signal-slot connections:<br />With direct connections, the slot gets called immediately when the signal is emitted. The slot is executed in the thread that emitted the signal (which is not necessarily the thread where the receiver object lives).<br />With queued connections, the slot is invoked when control returns to the event loop of the thread to which the object belongs. The slot is executed in the thread where the receiver object lives.<br />With auto connections (the default), the behavior is the same as with direct connections if the signal is emitted in the thread where the receiver lives; otherwise, the behavior is that of a queued connection.<br />With blocking queued connection, the behavior is the same as with queued connection, except that the current thread blocks until the slot has been delivered. This connection type should only be used for receivers in a different thread. Note that misuse of this type can lead to dead locks in your application.<br />
  14. 14. Signals and Slot Contd..<br />Using direct connections when the sender and receiver live in different threads is unsafe if an event loop is running in the receiver&apos;s thread, we need to use insure synchronization explicitly.<br />For Queued connections or for the AUTO connection when receiving thread lives on a different thread. <br />QT code internally sends event called QMetaCallEvent. <br />This event is handled by the QT event loop and it in turn calls qt_metacallwhich finally calls the slot function<br />Argument of signals are allocated and copied internally by the framework before posting event<br />
  15. 15. Internal Details<br />Mapping of Event framework to Symbian AO<br />Event Loop <br />
  16. 16. QT Events and Symbian<br />QT implements event dispatcher loop on Symbian using Active objects and Active scheduler<br />However it does not use default active scheduler loop which is started with CActiveScheduler::Start() <br />It manages its own event loop and use CActiveScheduler::WaitForAnyRequest() and CActiveScheduler::RunIfReady(..) methods of current active Scheduler. <br />Following Active Objects are created to help implement this <br />QWakeUpActiveObject: This active object helps in posted event functionality<br />QTimerActiveObject: This active object helps in delivering timeout expiry events.<br />QSocketActiveObject: This active object helps in delivering socket notification<br />QCompleteDeferredAOs: This active object for completing deferred operations like deferred delete<br />When event is posted , it is put in the thread specific queue and request completed for QWakeUpActiveObject<br />Event are delivered to target QObject from QWakeUpActiveObject::RunL() using QCoreApplicationPrivate::sendPostedEvents(0, 0, d-&gt;threadData);<br />Framework takes care of completing request on appropriate thread by using RThread::RequestComplete - While posting events<br />This is useful when event for a thread is posted from some other thread<br />
  17. 17. QT Event Loop<br />When we call Q[Core]Application::exec() at the end of our main() function, the application enters Qt&apos;s event loop. Conceptually, the event loop looks like this: <br />while (!exit_was_called) { <br /> while (!posted_event_queue_is_empty) { process_next_posted_event(); <br /> } <br /> while (!spontaneous_event_queue_is_empty) { process_next_spontaneous_event(); <br /> } <br /> while (!posted_event_queue_is_empty) { process_next_posted_event(); <br /> } <br />}<br />