Discussion on Event Processing Mechanism 2 of QT

Source: Internet
Author: User

 

In the previous article, we introduced the event processing mechanism of the QT framework: Event generation, distribution, acceptance, and processing, and analyzed the code by clicking qwidget in the Windows system as an example, I analyzed how the QT Framework processes the Message Queue cycle through event loop processing, how to assign the function to the platform step by step to obtain and package user input events for processing by the Windows system, the function call stack is as follows:

  1. Main (INT, char **)
  2. Qapplication: exec ()
  3. Qcoreapplication: exec ()
  4. Qeventloop: exec (processeventsflags)
  5. Qeventloop: processevents (processeventsflags)
  6. Qeventdispatcherwin32: processevents (qeventloop: processeventsflags)

 

This article describes how to send events to the receiver and processor qwidget: event (qwidget inherits objects, overload its virtual function event), all the discussions below will be embedded in the source code.

  1. QT_WIN_CALLBACK QtWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) bool QETWidget: translateMouseEvent (const MSG & msg)
  2. Bool QApplicationPrivate: sendMouseEvent (...)
  3. Inline bool QCoreApplication: sendmediataneousevent (QObject * receiver, QEvent * event)
  4. Bool QCoreApplication: notifyInternal (QObject * receiver, QEvent * event)
  5. Bool QApplication: notify (QObject * receiver, QEvent * e)
  6. Bool QApplicationPrivate: notify_helper (QObject * receiver, QEvent * e)
  7. Bool QWidget: event (QEvent * event)

// (Continued section 7) Section 2-1: <br/> qt_win_callback qtwndproc (hwnd, uint message, wparam, lparam) <br/>{< br/>... <br/> // check whether the message is a mouse event that can be escaped by QT <br/> If (qt_is_translatable_mouse_event (Message) {<br/> If (qapplication :: activepopupwidget ()! = 0) {<br/> point curpos = msg.pt; <br/> // obtain the qwidget pointer where the cursor is clicked, it points to the widget instance we created in main <br/> qwidget * w = qapplication: widgetat (curpos. x, curpos. y); <br/> If (w) <br/> widget = (qetwidget *) W; <br/>}< br/> If (! Qt_tabletchokemouse) {<br/> // right, right here. The Windows callback function distributes mouse events back to QT widgets <br/> // => section 2-2 <br/> result = widget-> translatemouseevent (MSG ); <br/>... <br/>}< br/> // section 2-2 $ qtdir/src/GUI/kernel/qapplication_win.cpp <br/> // The function is related to the Windows platform, the main responsibility is to unpackage mouse events packaged in Windows format and translate them into qmouseevents and qwidgets that can be identified by qapplication. <br/> bool qetwidget: translatemouseevent (const MSG & MSG) <br/>{< br/> //.. ignore the long code here <br/> // Let's take a look at the sendmouseevent declaration <br/> // Widget is the receiver of the event; e is the encapsulated qmouseevent <br/> // ==> section 2-3 <br/> res = qapplicationprivate: sendmouseevent (widget, & E, alienwidget, this, & qt_button_down, qt_last_mouse_receiver); <br/>}< br/> // section 2-3 $ qtdir/src/GUI/kernel/qapplication. CPP <br/> bool qapplicationprivate: sendmouseevent (qwidget * receiver, qmouseevent * event, <br/> qwidget * alienwidget, qwidget * nativewidget, <br/> qwidget ** Buttondown, qpointer <qwidget> & lastmousereceiver, <br/> bool spontaneous) <br/>{< br/> // now the Code related to the platform has been processed <br/> // The default sending method of mouseevent is mongotaneous, so sendmediataneousevent is executed. The sendmediataneousevent () and sendevent code implementations are almost the same, except for marking the spontaneous attribute of qevent. Here is an example of a taneous event: if an event is generated outside the application, such as a system event. Apparently, the mousepress event is an event generated by the Windows system (see section 1 ~ Section 7), so it is <br/> Spontaneous event <br/> If (spontaneous) <br/> result = qapplication: sendspontaneousevent (receiver, event ); ==> Section 2-4 <br/> else <br/> result = qapplication: sendevent (handler er, event); <br/>}< br/>

 

// Section 2-4 C:/QT/4.7.1-Vs/src/corelib/kernel/qcoreapplication. h <br/> inline bool qcoreapplication: sendmediataneousevent (qobject * receiver, qevent * event) <br/> {<br/> // mark the event as a spontaneous event <br/> // call 2-5 qcoreapplication: policyinternal <br/> If (Event) event-> success T = true; return self? Self-> policyinternal (handler er, event): false; <br/>}< br/> // section 2-5: $ qtdir/GUI/kernel/qapplication. CPP <br/> bool qcoreapplication: notifyinternal (qobject * receiver, qevent * event) <br/>{</P> <p> // several lines of code for Qt Jambi (QT Java bound version) and QSA (QT script for Application) <br/>... <br/> // The main purpose of the following code is that the QT force event can only be sent to objects in the current thread, that is, Cycler-> d_func ()-> threaddata should be equal to qthreaddata :: current (). Note: Cross-thread events need to be distributed using event loop <br/> qobjectprivate * D = ER er-> d_func (); <br/> qthreaddata * threaddata = D-> threaddata; <br/> ++ threaddata-> looplevel; <br/> bool returnvalue; <br/> qt_try {<br/> // wow, finally came to the famous function qcoreapplication :: nofity () ==> section 2-6 <br/> returnvalue = Policy (handler er, event); <br/>} qt_catch (...) {<br/> -- threaddata-> looplevel; <br/> qt_rethrow; <br/>}< br/> // Sec Tion 2-6: $ qtdir/GUI/kernel/qapplication. CPP <br/> // qcoreapplication: Notify and Its overload function qapplication: Notify play a core role in the QT dispatching process. what is said in the official documents of QT: the notify function is called when all events of any object in any thread are sent. <Br/> bool qapplication: Notify (qobject * receiver, qevent * E) <br/>{< br/> // The code is very long and the most important thing is a large switch, case <br/> .. <br/> switch (e-> type () <br/>{< br/>... <br/> case qevent: mousebuttonpress: <br/> case qevent: mousebuttonrelease: <br/> case qevent: mousebuttondblclick: <br/> case qevent: mousemove: <br/>... <br/> // set your own private class (D is the handle of the private class) to further process section 2-7 <br/> res = D-> policy_helper (W, W = rece Iver? Mouse: & Me); <br/> E-> Break T = false; <br/> break; <br/>}< br/>... <br/>}< br/> // section 2-7: $ qtdir/GUI/kernel/qapplication. CPP <br/> bool qapplicationprivate: notify_helper (qobject * receiver, qevent * E) <br/>{< br/>... <br/> // send this event to the Event Filter. Here we will introduce event filters. the Event Filter is an object that accepts all events to be sent to the target object. <Br/> // as shown in the code, it starts to process events before the action of the target object. The qobject: eventfilter () of the filter is called. It can accept or discard the filter and allow or reject further processing of the event. If all event filters allow further event processing, the event will be sent to the target object itself. If one of them stops processing, the target and any subsequent event filters cannot see any event. <Br/> If (sendthroughobjecteventfilters (handler er, E) <br/> return true; <br/> // submit the event to receiver ER => section 2-8 <br/> bool consumed = Receiver er-> event (E ); <br/> E-> partition T = false; <br/>}< br/> // section 2-8 $ qtdir/GUI/kernel/qwidget. CPP <br/> // qapplication uses notify and its private class notify_helper to distribute the event to the qobject subclass-qwidget. <br/> bool qwidget: event (qevent * event) <br/>{< br/>... <br/> switch (Event-> type () {<br/> case qevent: mousebuttonpress: <br/> // don't reset input context here. whether reset or not is <br/> // a responsibility of input method. reset () will be <br/> // called by mousehandler () of input method if necessary <br/> // via mousepressevent () of text widgets. <br/> # If 0 <br/> resetinputcontext (); <br/> # endif <br/> // mousepressevent is a virtual function, the subclass of qwidget can redefine the behavior of the mousepress event by reloading <br/> mousepressevent (qmouseevent *) event); <br/> break; <br/>}

 

 

 

 

 

 

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.