Qt5 與 Qt4 的點點差別------事件

Qt5相對於Qt4 增長對事件accept()和ignore()函數。web

Qt 中有不少種事件:鼠標事件、鍵盤事件、大小改變的事件、位置移動的事件等等。對於事件的處理,咱們Qt 中使用相對應的機制。
event()函數
1. event()函數是一個 protected 的函數,這意味着咱們要想重寫event(),必須繼承一個已有的類。
2. 各個組件對事件處理是併發修改,仍是挨個修改呢?併發

bool Test::event(QEvent *e)
{
    if (e->type() == QEvent::KeyPress) {
        QKeyEvent *keyEvent = static_cast<QKeyEvent *>(e);
        if (keyEvent->key() == Qt::Key_Tab) {
            qDebug() << "You press tab.";
            return true;
        }
    }
    return QWidget::event(e);
}

 

eventFilter()函數
app

virtual bool QObject::eventFilter ( QObject * watched, QEvent * event );
bool Test::eventFilter(QObject *object, QEvent *event)
{
    if (object == target && event->type() == QEvent::KeyPress) {
        QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
        if (keyEvent->key() == Qt::Key_Tab) {
            qDebug() << "You press tab.";
            return true;
        } else {
            return false;
        }
    }
    return false;
}

總結Qt 的事件處理
1.  重寫paintEvent()、mousePressEvent()等事件處理函數。這是最普通、最簡單的形式,同時功能也最簡單。
2. 重寫event()函數。event()函數是全部對象的事件入口,QObject和QWidget中的實現,默認是把事件傳遞給特定的事件處理函數。
3. 在特定對象上面安裝事件過濾器。該過濾器僅過濾該對象接收到的事件。
4. 在QCoreApplication::instance()上面安裝事件過濾器。該過濾器將過濾全部對象的全部事件,所以和notify()函數同樣強大,可是它更靈活,由於能夠安裝多個過濾器。全局的事件過濾器能夠看到 disabled 組件上面發出的鼠標事件。全局過濾器有一個問題:只能用在主線程。(受線程影響)
5. 重寫QCoreApplication::notify()函數。這是最強大的,和全局事件過濾器同樣提供徹底控制,而且不受線程的限制。可是全局範圍內只能有一個被使用(由於QCoreApplication是單例的)。函數

 

class Label : public QWidget
{
public:
    Label()
    {
        installEventFilter(this);
    }
    bool eventFilter(QObject *watched, QEvent *event)
    {
        if (watched == this) {
            if (event->type() == QEvent::MouseButtonPress) {
                qDebug() << "eventFilter";
            }
        }
        return false;
    }
protected:
    void mousePressEvent(QMouseEvent *)
    {
        qDebug() << "mousePressEvent";
    }
    bool event(QEvent *e)
    {
        if (e->type() == QEvent::MouseButtonPress) {
            qDebug() << "event";
        }
        return QWidget::event(e);
    }
};
class EventFilter : public QObject
{
public:
    EventFilter(QObject *watched, QObject *parent = 0) :
        QObject(parent),
        m_watched(watched)
    {
    }
    bool eventFilter(QObject *watched, QEvent *event)
    {
        if (watched == m_watched) {
            if (event->type() == QEvent::MouseButtonPress) {
                qDebug() << "QApplication::eventFilter";
            }
        }
        return false;
    }
private:
    QObject *m_watched;
};
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    Label label;
    app.installEventFilter(new EventFilter(&label, &label));
    label.show();
    return app.exec();
}

輸出結果是:post

QApplication::eventFilter 
eventFilter 
event 
mousePressEvent

所以能夠知道,全局事件過濾器被第一個調用,以後是該對象上面的事件過濾器,其次是event()函數,最後是特定的事件處理函數。this

 

registerEventType()函數   ------- 用於自定義事件的註冊spa

static int QEvent::registerEventType ( int hint = -1 );

發送方式:.net

static bool QCoreApplication::sendEvent(QObject *receiver,QEvent *event);

例子:線程

QMouseEvent event(QEvent::MouseButtonPress, pos, 0, 0, 0);
QApplication::sendEvent(mainWindow, &event); 
static void QCoreApplication::postEvent(QObject *receiver,QEvent *event);

注意:在事件被髮送的時候,event對象並不會被銷燬。一般咱們會在棧上建立event對象code

 

參考資料:

http://www.devbean.net/2012/10/qt-study-road-2-event-summary/

相關文章
相關標籤/搜索