事件分發(event)

Qt的event()函式不直接處理事件,而是將這些事件對象,按照它們的類型,分發給不同的事件處理器(event handler),所以如果想在事件分發之前做一些操作,可以重載event()函數,這邊以繼承自QWidget的自定義Widget元件,重載原本的event()函式,當我們按下Up或Down鍵,此時QLabel上會顯示按下的鍵。


widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QLabel>
#include <QVBoxLayout>
#include <QEvent>
#include <QKeyEvent>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    bool event(QEvent *e);
private:
    QLabel *upLabel;
    QLabel *downLabel;
    QVBoxLayout *mainLayout;
};

#endif 

widget.cpp

#include "widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent)
{
    setWindowTitle(tr("event事件"));
    upLabel = new QLabel(this);
    downLabel = new QLabel(this);

    upLabel->setText(tr(""));
    downLabel->setText(tr(""));

    upLabel->setAlignment(Qt::AlignCenter);      //label文字置中
    downLabel->setAlignment(Qt::AlignCenter);

    mainLayout = new QVBoxLayout(this);
    mainLayout->addWidget(upLabel);
    mainLayout->addWidget(downLabel);
}
bool Widget::event(QEvent *e){
    if(e->type() == QEvent::KeyPress) {
        QKeyEvent *keyEvent = static_cast<QKeyEvent *>(e);
        if(keyEvent->key() == Qt::Key_Up) {
            upLabel->setText(tr("Up鍵被按下"));
            downLabel->setText(tr(""));
            return true;
        }
        if(keyEvent->key() == Qt::Key_Down) {
            downLabel->setText(tr("Down鍵被按下"));
            upLabel->setText(tr(""));
            return true;
        }
    }
    return QWidget::event(e); //對於其它不關心的事件,調用父類的event()函數繼續轉發
}

main.cpp

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.resize(200,200);
    w.show();

    return a.exec();
}

event

我們使用QEvent::type()函數檢查事件的類型,處理自己感興趣的事件之後返回true,表示已經對此事件進行了處理,對於其它不關心的事件,則調用父類別的event()函數繼續轉發,否則這個組件就只能處理我們定義的事件了。