Anatomy of the event distribution source in QT (total 8 steps, the sequence is very clear: the global event filter, then the event filter passed to the target object, eventually passed to the target object)

Source: Internet
Author: User

Anatomy of event distribution source code in QT

Event delivery sequence in QT:

In a supposed program, it goes into an event loop, accepts the events generated by the system, and distributes them, all in exec.
The following examples illustrate:

1) First Look at the following example code: [CPP]View Plaincopy
    1. int main (int argc, char *argv[])
    2. {
    3. Qapplication A (argc, argv);
    4. MouseEvent W;
    5. W.show ();
    6. return a.exec ();
    7. }
2) a.exec into the event loop, call is qapplication::exec (); [CPP]View Plaincopy
    1. int Qapplication::exec ()
    2. {
    3. return <span style="color: #ff6666;" >qguiapplication::exec ();</span>
    4. }
3) Qapplication::exec () is called qguiapplication::exec (); [CPP]View Plaincopy
    1. int Qguiapplication::exec ()
    2. {
    3. #ifndef qt_no_accessibility
    4. Qaccessible::setrootobject (Qapp);
    5. #endif
    6. return qcoreapplication::exec ();
    7. }
4) Qguiapplication::exec () is called qcoreapplication::exec (); [CPP]View Plaincopy
  1. int Qcoreapplication::exec ()
  2. {
  3. if (! Qcoreapplicationprivate::checkinstance ("exec"))
  4. return-1;
  5. Qthreaddata *threaddata = Self->d_func ()->threaddata;
  6. if (threaddata! = Qthreaddata::current ()) {
  7. Qwarning ("%s::exec:must is called from the main thread", Self->metaobject ()->classname ());
  8. return-1;
  9. }
  10. if (!threaddata->eventloops.isempty ()) {
  11. Qwarning ("Qcoreapplication::exec:the event loop is already running");
  12. return-1;
  13. }
  14. Threaddata->quitnow = false;
  15. Qeventloop EventLoop;
  16. Self->d_func ()->in_exec = true;
  17. Self->d_func ()->abouttoquitemitted = false;
  18. int returncode = eventloop.exec ();
  19. Threaddata->quitnow = false;
  20. if (self) {
  21. Self->d_func ()->in_exec = false;
  22. if (!self->d_func ()->abouttoquitemitted)
  23. Emit Self->abouttoquit (Qprivatesignal ());
  24. Self->d_func ()->abouttoquitemitted = true;
  25. Sendpostedevents (0, Qevent::D eferreddelete);
  26. }
  27. return ReturnCode;
  28. }
5) qcoreapplication::exec () call Eventloop.exec () for Event loop; [CPP]View Plaincopy
  1. int qeventloop::exec (Processeventsflags flags)
  2. {
  3. Q_d (Qeventloop);
  4. //we need to protect from race condition with Qthread::exit
  5. Qmutexlocker Locker (&static_cast<qthreadprivate *> (qobjectprivate::get ( d->threaddata->  Thread)) (->mutex);
  6. if (d->threaddata->quitnow)
  7. return-1;
  8. if (d->inexec) {
  9. Qwarning ("Qeventloop::exec:instance%p have already called EXEC ()", this );
  10. return-1;
  11. }
  12. struct Loopreference {
  13. Qeventloopprivate *d;
  14. Qmutexlocker &locker;
  15. bool Exceptioncaught;
  16. Loopreference (qeventloopprivate *d, Qmutexlocker &locker): D (d), Locker (Locker), Exceptioncaught (true)
  17. {
  18. D->inexec = true;
  19. D->exit = false;
  20. ++d->threaddata->looplevel;
  21. D->threaddata->eventloops.push (D->q_func ());
  22. Locker.unlock ();
  23. }
  24. ~loopreference ()
  25. {
  26. if (exceptioncaught) {
  27. Qwarning ("Qt has caught a exception thrown from an event handler. throwing\n "
  28. "Exceptions from a event handler is not a supported in Qt. You must\n "
  29. "Reimplement qapplication::notify () and catch all Exceptions there.\n");
  30. }
  31. Locker.relock ();
  32. Qeventloop *eventloop = D->threaddata->eventloops.pop ();
  33. q_assert_x (EventLoop = = D->q_func (), "qeventloop::exec ()", "Internal Error");
  34. Q_unused (EventLoop); //--release warning
  35. D->inexec = false;
  36. --d->threaddata->looplevel;
  37. }
  38. };
  39. Loopreference ref (d, Locker);
  40. //Remove posted Quit events when entering a new event loop
  41. Qcoreapplication *app = Qcoreapplication::instance ();
  42. if (app && app->thread () = = Thread ())
  43. Qcoreapplication::removepostedevents (app, qevent::quit);
  44. While (!d->exit)
  45. Processevents (Flags | waitformoreevents |  EVENTLOOPEXEC);
  46. Ref.exceptioncaught = false;
  47. return d->returncode;
  48. }
6) eventloop.exec () call Qcoreapplication's processevents for event distribution; 7) call Notify for distribution

Qcoreapplication::sendevent, Qcoreapplication::p ostevent and Qcoreapplication::sendpostedevents all call notify for event distribution;

[CPP]View Plaincopy
  1. BOOL Qcoreapplication::notify (Qobject *receiver, qevent *event)
  2. {
  3. Q_d (qcoreapplication);
  4. //No events is delivered after ~qcoreapplication () have started
  5. if (qcoreapplicationprivate::is_app_closing)
  6. return true;
  7. if (receiver = = 0) { //serious error
  8. Qwarning ("qcoreapplication::notify:unexpected null receiver");
  9. return true;
  10. }
  11. #ifndef Qt_no_debug
  12. D->checkreceiverthread (receiver);
  13. #endif
  14. return Receiver->iswidgettype ()? false: <span style="color: #ff6666;"  > d->notify_helper</span> (receiver, event);
  15. }
8) Notify call Notify_helper for event distribution; [CPP]View Plaincopy
  1. BOOL Qcoreapplicationprivate::notify_helper (Qobject *receiver, qevent * Event)
  2. {
  3. //Send to all application event filters
  4. if (sendthroughapplicationeventfilters (receiver, event))
  5. return true;
  6. //Send to all receiver event filters
  7. if (sendthroughobjecteventfilters (receiver, event))
  8. return true;
  9. //Deliver the event
  10. return receiver->event (event);
  11. }
9) from the code in the 8th step above, you can see the event passing

The order of delivery is first passed to the global event filter, then to the target object's event filter, and finally passed to the target object.

http://blog.csdn.net/chenlong12580/article/details/25009095

Anatomy of the event distribution source in QT (total 8 steps, the sequence is very clear: the global event filter, then the event filter passed to the target object, eventually passed to the target object)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.