Qt中的事件

來源:互聯網
上載者:User

1.事件的來源
來源於
a)windows系統的事件,經Qt的封裝(如QMouseEvent);
b)Qt內建的事件(如QTimerEvent);
c)應用程式自訂的事件
 
2.處理事件的位置
2.1 重載虛擬方法
比如一個按鈕,要自訂左鍵click時的行為,可以這樣做:
a. 從一個QPushButton上派生一個子類如MyPushButton
b. 重載void MyPushButton::mousePressEvent(QMouseEvent *event)
* 一般來講,除非要重新改寫這個事件的預設行為,否則如果僅是為了擴充其功能,最好在函數的最後call預設的父類處理方法,如QPushButton::mousePressEvent(event);
* 在調用mousePressEvent這些特定的事件前,先調用通用事件處理函數,QObject::event()。因此,對於一些特殊情況,我們必須 要重定義event(),如我們要對tab鍵進行重定義。預設的tab鍵是將focus移到下一個widget上去。比如在一個text edit widget裡,我們可能希望tab鍵是向右形成一個置表位置,這時需要在text edit widget的event()進行處理。

2.2 event filter(事件過濾器)方法
一個對象的event filter的處理優先順序在 該對象的 event()方法調用之前。這時,filter對象的eventFilter()方法被調用
* 使用QCoreApplication的事件過濾,可以將任何事件在進行具體對象之前,進行處理。但需要注意,這可能會使得整個事件處理過程變慢。

  • Reimplementing QCoreApplication::notify. This is very powerful, providing complete control; but only one subclass can be active at a time.
  • Installing an event filter on QCoreApplication::instance(). Such an event filter is able to process all events for all widgets, so it's just as powerful as reimplementing notify(); furthermore, it's possible to have more than one application-global event filter. Global event filters even see mouse events for disabled widgets.
  • Reimplementing QObject::event() (as QWidget does). If you do this you get Tab key presses, and you get to see the events before any widget-specific event filters.
  • Installing an event filter on the object. Such an event filter gets all the events except Tab and Shift-Tab key presses.
  • Reimplementing paintEvent(), mousePressEvent() and so on. This is the commonest, easiest and least powerful way.

3. 自訂事件
3.1 自訂事件從QEvent派出,該event number必須大於QEvent::User
3.2 使用postEvent和sendEvent方法派遣自訂事件
* postEvent實質是將事件推進事件迴圈(event loop),馬上返回。事件的實際發送可能在稍後的一個事件處理時鐘內。
* 在某種意義上,程式可以直接調用對象的對應事件函數,而繞過postEvent。但存在不足,
a)很多事件處理函數是protected,意味著你不能直接調用;
b)這種直接調用將繞過event filter;Qt的解決方案是sendEvent。比如repaint()實質是調用了sendEvent。
* sendEvent等待事件被發送成功或失敗後才返回。
* postEvent的一個好處是多個posted的event可以被壓縮成單一的event,從而提高了效率。
* 可以使用QCoreApplication::sendPostedEvents強迫Qt馬上進入事件迴圈(event loop)派遣事件。
 
4. 事件的傳播(propogation)
如果事件在目標對象上得不到處理,事件向上一層進行傳播,直到最頂層的widget為止。
如果得到事件的對象,調用了accept(),則事件停止繼續傳播;如果調用了ignore(),事件向上一級繼續傳播。
Qt對自訂事件處理函數的預設傳回值是accept(),但預設的事件處理函數是ingore()。因此,如果要繼續向上傳播,調用QWidget的預設處理函數即可。到時為止的話,不必顯式調用accept()。
但在event處理函數裡,返回true表示accept,返回false表示向上級傳播。
* 在closeEvent是個特殊情形,accept表示quit,ignore表示取消,所以最好在closeEvent顯式調用accept和ignore。
 
5. tips
5.1 使用event->type得到事件的具體類型,對之進行判斷,是否是需要的類型(比如KeyPress),然後進行相應處理
5.2 使用static_cast<specific event type *>對通用事件轉換成特定類型,比如將event轉成QKeyEvent *,然後調用QKeyEvent::key()取得按下什麼鍵。
5.3 使用sendEvent時,參數 event,必須是局部變數,因為sendEvent不負責對event的刪除。而postEvent的event參數,則必須是 new分配的heap對象,post完了後會自動刪除。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.