小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Qt的事件處理機(jī)制分析

 寂靜如河 2012-08-09
如果對MFC有點了解,可以近似的把Qt的信號(signal)和事件(event)對應(yīng)于MFC的命令(command)和消息(message) ,事件是窗口系統(tǒng)或者qt對不同情況的響應(yīng),絕大多數(shù)被產(chǎn)生的事件都是對用戶行為的響應(yīng),但是也有一些,比如定時器事件,它們是被系統(tǒng)獨立產(chǎn)生的。QWidget::event()虛函數(shù)是各種事件的一個大管家,負(fù)責(zé)把大多數(shù)常用類型的事件傳遞給特定的事件處理器(事件處理函數(shù),也都是虛擬函數(shù),便于其繼承子類對于該事件處理的編程),可以分析一下事件總管QWidget::event()虛函數(shù)的部分源碼(完整源碼在C:/Qt/4.2.2/src/gui/kernel/qwidget.cpp中qwidget::event()函數(shù)的定義):
QEvent類實現(xiàn)對事件的封裝。The QEvent class is the base class of all event classes. Event objects contain event parameters.

bool QWidget::event(QEvent *event)
{
    Q_D(QWidget);

    // ignore mouse events when disabled
    if (!isEnabled()) {
        switch(event->type()) {
        case QEvent::TabletPress:
        case QEvent::TabletRelease:
        case QEvent::TabletMove:
        case QEvent::MouseButtonPress:
        case QEvent::MouseButtonRelease:
        case QEvent::MouseButtonDblClick:
        case QEvent::MouseMove:
        case QEvent::ContextMenu:
#ifndef QT_NO_WHEELEVENT
        case QEvent::Wheel:
#endif
            return false;
        default:
            break;
        }
    }
    switch (event->type()) {            //判斷事件類型
    case QEvent::MouseMove:
        mouseMoveEvent((QMouseEvent*)event);           //將鼠標(biāo)移動類型的事件分派給mouseMoveEvent函數(shù)處理
        break;

    case QEvent::MouseButtonPress:
    // Don't reset input context here. Whether reset or not is
    // a responsibility of input method. reset() will be
    // called by mouseHandler() of input method if necessary
    // via mousePressEvent() of text widgets.
#if 0
        resetInputContext();
#endif
        mousePressEvent((QMouseEvent*)event);
        break;

    case QEvent::MouseButtonRelease:
        mouseReleaseEvent((QMouseEvent*)event);
        break;

    case QEvent::MouseButtonDblClick:
        mouseDoubleClickEvent((QMouseEvent*)event);
        break;
#ifndef QT_NO_WHEELEVENT
    case QEvent::Wheel:
        wheelEvent((QWheelEvent*)event);
        break;
#endif
……
……
然后在需要處理該事件的QWidget派生類中重寫響應(yīng)的事件處理函數(shù)(覆蓋默認(rèn)的虛函數(shù),如event,keyPressEvent等函數(shù))來完成在該派生類對象中對該事件的響應(yīng)。

關(guān)于對事件過濾器的編程,一般分兩步:
1、通過對目標(biāo)對象(被監(jiān)視對象)調(diào)用installEventFilter()函數(shù)來注冊監(jiān)視對象;
2、在監(jiān)視對象的eventFilter函數(shù)中處理目標(biāo)對象的事件。(可以認(rèn)為監(jiān)視對象攔截了目標(biāo)對象的事件)

下面用代碼來說明事件處理處理和事件過濾:

//newlineedit.h
#ifndef NEWLINEEDIT_H
#define NEWLINEEDIT_H

#include <QLineEdit>
#include "ui_newlineedit.h"

class newLineEdit : public QLineEdit
{
    Q_OBJECT

public:
    newLineEdit(QWidget *parent = 0);
    ~newLineEdit();

    bool event(QEvent *event);      //重寫event虛函數(shù)來處理特定的事件

private:
    Ui::newLineEditClass ui;
};

#endif // NEWLINEEDIT_H

//www.h
#ifndef WWW_H
#define WWW_H

#include <QtGui/QMainWindow>
#include "ui_www.h"

class www : public QMainWindow
{
    Q_OBJECT

public:
    www(QWidget *parent = 0, Qt::WFlags flags = 0);
    ~www();

    bool eventFilter(QObject *target, QEvent *event);      //重寫eventFilter虛函數(shù)來攔截特定的事件

private:
    Ui::wwwClass ui;
};

#endif // WWW_H


//newlineedit.cpp
#include "newlineedit.h"
#include <QKeyEvent>

newLineEdit::newLineEdit(QWidget *parent)
    : QLineEdit(parent)
{
    ui.setupUi(this);
}
bool newLineEdit::event(QEvent *event)
{
    if (event->type() == QEvent::KeyPress)
    {
        QKeyEvent *keyEvent = (QKeyEvent *)event;  
        if (keyEvent->key() == Qt::Key_Tab)      //判斷特定的事件,作出自定義的處理
        {
            insert("/t");
            return true;
        }
    }
    return QWidget::event(event);      //將不需要特定處理的事件交給默認(rèn)的基類event()函數(shù)處理
}
newLineEdit::~newLineEdit()
{

}


//www.cpp
#include "www.h"
#include <QKeyEvent>

www::www(QWidget *parent, Qt::WFlags flags)
    : QMainWindow(parent, flags)
{
    ui.setupUi(this);
    ui.lineEdit->installEventFilter(this);       //注冊this監(jiān)視ui.lineEdit對象,this攔截ui.lineEdit的某些事件

bool www::eventFilter(QObject *target, QEvent *event)
{
    if (target == ui.lineEdit && event->type() == QEvent::KeyPress
        && ((QKeyEvent *)event)->key() == Qt::Key_Tab)     //判斷監(jiān)視攔截條件是否滿足,如是,則攔截該事件
    {
        ui.lineEdit->insert(tr("filter completed!"));
        return true;
    }
    return QMainWindow::eventFilter(target, event);
}

www::~www()
{

}

然后我們再來分析一下QObject::installEventFilter函數(shù)的源碼,看其是如何實現(xiàn)過濾功能的:
void QObject::installEventFilter(QObject *obj)
{
    Q_D(QObject);
    if (!obj)
        return;

    QWriteLocker locker(QObjectPrivate::readWriteLock());

    // clean up unused items in the list
    d->eventFilters.removeAll((QObject*)0);
    d->eventFilters.removeAll(obj);
    d->eventFilters.prepend(obj);
}
可以參考下一篇分析QObject的文章.

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多