7-1 rewrite the event handler (reimplementing event handlers)

Source: Internet
Author: User
Tags drawtext

In QT, an event is the object of the subclass of qevent. Qt can process hundreds of types of events. Each type of events is determined by an enumeration value. For example, for a mouse click event, qevent: type () returns qevent: mousebuttonpress. In many cases, a qevent object cannot store all information about the event. For example, if you click an event, you need to save it as a left-click or right-click event to trigger this information, you also need to know the cursor position when an event occurs. The additional information is stored in the qmouseevent subclass of qevent. The QT object obtains information about the event through qobject: event. Qwidget: event () provides many common types of information and implements many event processing functions, such as mousepressevent (), keypressevent (), and paintevent. In the previous sections, we have seen many event processing functions in the mainwindow class, iconeditor class, and plotter class. In the qevent reference document, we also listed many types of events. We can also define our own events to dispatch events. Here, we will discuss two most common events: Keyboard Events and time events. The rewrite functions keypressevent () and keyreleaseevent () can process Keyboard Events. The plotter control overwrites the keypressevent () function. Generally, we only need to override keypressevent (), and only the key (CTRL, shift, alt) that needs to be modified to handle the keyboard release event, and the key information can be obtained through qkeyevent: modifiers (). For example, if we override the keypressevent () function of the codeeditor control, distinguish the Home key from the CTRL + HOME key: void codeeditor: keypressevent (qkeyevent * event) {Switch (Event-> key () {Case QT: key_home: If (Event-> modifiers () & QT: controlmodifier) {gotobeginningofdocument ();} else {gotobeginningofline ();} break; Case QT: key_end :... default: qwidget: keypressevent (event) ;}} the tab key and the backtab (SHIFT + TAB) Key are special. Before the control calls keypressevent (), The two keys are used to transfer the input focus to the previous control or the next control. In codeeditor, the tab key is expected to be indented, you can rewrite event (): bool codeeditor: event (qevent * event) {If (Event-> type () = qevent: keypress) in this way) {qkeyevent * keyevent = static_cast <qkeyevent *> (event); If (keyevent-> key () = QT: key_tab) {insertatcurrentposition ('/t '); return true ;}} return qwidget: event (event);} if this event is a keyboard strike event, we convert the qevent object to qkeyevent, and then confirm that the key is hit, if it is a tab key, true is returned after processing, Notify QT that we have handled the event. If false is returned, QT also submits the event to the base class control for processing. A better way to respond to keyboard events is to use qaction. For example, gotobeginningofline () and gotobeginningofdocument () are two public slot functions of codeeditor, and codeeditor is the central control of mainwindow. The following code binds the keyboard and slot functions: mainwindow :: mainwindow () {editor = new codeeditor; setcentralwidget (editor); gotobeginningoflineaction = new qaction (TR ("go to beginning of line"), this ); gotobeginningoflineaction-> setshortcut (TR ("home"); Connect (gotobeginningoflineaction, signal (activated (), editor, slot (gotobeginn Ingofline (); gotobeginningofdocumentaction = new qaction (TR ("go to beginning of document"), this); gotobeginningofdocumentaction-> setshortcut (TR ("Ctrl + home ")); connect (gotobeginningofdocumentaction, signal (activated (), editor, slot (gotobeginningofdocument ()));...} in this way, you can easily add a keyboard hitting command to the menu or toolbar. If the command does not appear on the user interface, you can use the qshortcut object instead of the qaction object. In qaction, you can use this class to bind the keyboard. Normally, as long as there are activated controls in the window, the control can be bound to the keyboard set by qaction and qshortcut. The bound key can be modified using qaction: setshortcutcontext () or q1_cur: setcontext. Another common event type is time events. Other events are triggered by a user's activity, while time events enable the program to execute a specific task at a certain interval. A time event is generally used to make the cursor flash, play an animation, or just draw a display interface or control. To introduce time events, we will implement a ticker control. This control displays a slogan that moves a pixel to the left every 30 milliseconds. If the widget is wider than the target widget, the text of the target widget is repeatedly displayed on the widget to fill up the entire widget. Figure 7.1. Ticker Widget


The header file is as follows: # ifndef ticker_h # define ticker_h # include <qwidget> class ticker: Public qwidget {q_object q_property (qstring text read text write settext) public: ticker (qwidget * parent = 0); void settext (const qstring & newtext); qstring text () const {return mytext;} qsize sizehint () const; protected: void paintevent (qpaintevent * event); void timerevent (qtimerevent * event); void showevent (qshowevent * event ); Void hideevent (qhideevent * event); Private: qstring mytext; int offset; int mytimerid ;}; # endif in the header file, we implement four event processing functions of ticker, three of them are timeevent (), showevent (), and hideevent () which we have never seen before. The following is the implementation file: # include <qtgui> # include "ticker. H "ticker: ticker (qwidget * parent): qwidget (parent) {offset = 0; mytimerid = 0;} in the constructor, Set offset to 0, this variable is the X coordinate value to be displayed in the text. The time ID is always not 0. Setting mytimerid to 0 indicates that we have not started any time. Void ticker: settext (const qstring & newtext) {mytext = newtext; Update (); updategeometry () ;}function settext () sets the text to be displayed. Calling Update () triggers a drawing event to re-display the text. updategeometry () notifies the layout manager to change the control size. Qsize ticker: sizehint () const {return fontmetrics (). size (0, text ();} returned by the sizehint () function is the required size for the control to fully display different texts. Qwidget: fontmetrics () returns a qfontmetrics object to obtain the font information of the control. Here we need to get the text size. (In qfontmetrics: size (), the first parameter is an identifier, which is not required for strings. All values are assigned 0 ). Void ticker: paintevent (qpaintevent */* event */) {qpainter painter (this); int textwidth = fontmetrics (). width (text (); If (textwidth <1) return; int x =-offset; while (x <width () {painter. drawtext (x, 0, textwidth, height (), QT: alignleft | QT: alignvcenter, text (); X ++ = textwidth ;}} function paintevent () use qpainter: drawtext () to draw text. Call fontmetrics () to obtain the horizontal space required by the text, and draw the text multiple times until the entire control is filled up. Void ticker: showevent (qshowevent */* event */) {mytimerid = starttimer (30);} showevent () starts a timer. Call qobject: starttimer () to return an id value, which helps us identify this timer. Qobject supports multiple independent timers at different time intervals. After starttimer () is called, QT generates an event every 30 milliseconds. The accuracy of the time depends on different operating systems. You can also call starttimer () in the ticker constructor (). However, starting a widget after it is visible can save some resources. Void ticker: timerevent (qtimerevent * event) {If (Event-> timerid () = mytimerid) {++ offset; If (Offset> = fontmetrics (). width (text () offset = 0; scroll (-1, 0);} else {qwidget: timerevent (event) ;}} function timerevent () it is called by the system at a certain interval. Increase the offset value by 1 to simulate text movement. When the offset value is increased to the width of the text, the text width is reset to 0. Call scroll () to scroll the control to the left to a pixel. You can also call Update (), But scroll () is more efficient. It moves visible pixels, but calls the draw event for the place where new painting is needed (in this example, is only a pixel-wide area ). If the timer is not what we need to handle, pass it to the base class. Void ticker: hideevent (qhideevent */* event */) {killtimer (mytimerid);} In hideevent (), call qobject: killtimer () to stop the timer. The priority of time events is very low. If multiple timers are required, it is time-consuming to trace the ID of each timer. In this case, a better way is to create a qtimer object for each timer. During each interval, qtimer sends a timeout () signal. Qtimer also supports a one-time timer (a timer that sends only one timeout () signal ).


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.