| 不
同類型的事件,都有對應的事件處理函式,它們接受QEvent的特定子類別實例作為引數,像是下例中mousePressEvent()事件處理函式上的
QMouseEvent,您可以針對事件的某些狀況作特定處理,而其它未處理的狀況,則呼叫父類別對應的的事件處理函式,讓父類別預先定義的事件處理可以
完成:
void CustomLabel::mousePressEvent(QMouseEvent *event) {
if (event->button() == Qt::LeftButton) { // 處理左鍵按下 // .... } else { // 由父類別所定義的事件處理函式來事件 QLabel::mousePressEvent(event); } } void CustomLabel::mouseReleaseEvent(QMouseEvent *event) { // 滑鼠放開事件處理.... } 事實上,每個可傳播的事件都有accept()與igore()兩個方法,用以告知Qt應用程式,這個事件處理者是否接受或忽略此 一事件,如果事件處理者中呼叫事件的accept(),則事件不會再進一步傳播,若呼叫了ignore(),則Qt應用程式會嘗試尋找另一個事件的接受者,您可以藉由isAccepted()方法得知事件是否被接受。 一般來說,除了QCloseEvent之外,很少直接呼叫accept()或ignore(),如果您接受事件,則在事件處理者當中實作對事件的處理(如上例的if陳述句),如果您不 接受事件,則直接呼叫父類別的事件實作(如上例的else陳述句),對於QWidget來說,預設的實作是: void QWidget::keyPressEvent(QKeyEvent *event) {
event->ignore(); } 由於QWidget預設的實作是呼叫ignore(),這讓事件可以向父元件傳播。 QCloseEvent則建議直接呼叫accept()與ignore(),accept()方法會繼續關閉的操作,ignore()則會取消關閉的操作: void MainWindow::closeEvent(QCloseEvent *event) {
if (continueToClose()) { event->accept(); } else { event->ignore(); } } QObject的event()方法通常用於分派事件,但在某些情況下,您希望在事件分派給其它事件處理者之 前,先行作一些處理,則可以重新定義event()方法,例如在視窗程式中,Tab鍵按下時希望其將焦點移至下一個圖型元件,而不是直接讓目前焦點的圖形 元件直接處理Tab鍵,則您可以在繼承QWidget子類別時,重新定義其event()方法,例如: bool CustomWidget::event(QEvent *event) {
if (event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); if (keyEvent->key() == Qt::Key_Tab) { // 處理Tab鍵 return true; } } return QWidget::event(event); } 在執行時期想要知道所取得之QEvent類型,可以使用QEvent的type()方法取得常數值,並與QEvent::Type作比對。 事件若順利處理完畢,則要傳回true,表示這個事件被接受並處理,QApplication可以繼續事件佇列中的下一個事件處理,若傳回false,則QApplication嘗試尋找下一個可以處理事件的方法。 您不用呼叫事件的accept()或ignore(),這也沒有意義,accept()或ignore()是用來在特定的事件處理者之間作溝通,而 event()的true或false,是用來告知QApplication的notify()方法是否處理下一事件,以QWidget的event() 實作來說,它是根據事件的isAccepted()來判斷該傳回true或false: bool QWidget::event(QEvent *event) {
switch (e->type()) { case QEvent::KeyPress: keyPressEvent((QKeyEvent *)event); if (!((QKeyEvent *)event)->isAccepted()) return false; break; case QEvent::KeyRelease: keyReleaseEvent((QKeyEvent *)event); if (!((QKeyEvent *)event)->isAccepted()) return false; break; ... } return true; } 另一個重新定義event()的情況是自訂QCustomEvent子類型時,您可以將之分派給其它函式或直接在event()中處理,例如: bool CustomWidget::event(QEvent *event) {
if (event->type() == MyCustomEventType) { CustomEvent *myEvent = static_cast<CustomEvent *>(event); // 對自訂事件的處理,或呼叫其它函式來處理事件 return true; } return QWidget::event(event); } 自訂事件必須是QCustomEvent的子類別,您也可以直接實作customEvent()方法來處理自訂事件,詳可參考 自訂與傳送事件。 |