installeventfilter —— 一個事件過濾器

installeventfilter作為Qt GUI編程中的一個重要組成部分,在Qt很多實際開發項目中經常被使用。installeventfilter的作用是為對象安裝一個事件過濾器,從而可以截獲對象的事件。在下面的文章中,我們將從多個方面來詳細探討installeventfilter的作用、使用方法和可能的異常情況。

一、installeventfilter無法

1、安裝事件過濾器失敗
如果對象的繼承鏈中沒有eventFilter函數實現,則調用installEventFilter()函數時會失敗,應該確保對象中eventFilter函數的重載實現。

    class CustomWidget : public QWidget
    {
        Q_OBJECT
    
    public:
        explicit CustomWidget(QWidget *parent = nullptr);
    
    protected:
        bool eventFilter(QObject *obj, QEvent *event) override;
    }
    
    CustomWidget::CustomWidget(QWidget *parent)
        : QWidget(parent)
    {
        QWidget *button = new QPushButton();
        button->installEventFilter(this); // 此處將控制項button的事件過濾器設置為CustomWidget,需確保CustomWidget實現了eventFilter函數
    }
    
    bool CustomWidget::eventFilter(QObject *obj, QEvent *event)
    {
        Q_UNUSED(obj);
        if (event->type() == QEvent::MouseMove) {
            // 在此處理移動事件
            return true;
        }
        return QWidget::eventFilter(obj, event);
    }

2、事件過濾器重複設置
使用一個對象為另一個對象安裝一個事件過濾器時,應該確保只能安裝一次。因為重複安裝會造成事件被多次過濾,從而產生意料之外的結果。

    QWidget *button = new QPushButton();
    if (!button->parent()) {
        // 檢查button是否已有父對象
        CustomWidget *widget = new CustomWidget();
        button->installEventFilter(widget);
    }

二、installeventfilter 異常退出

1、事件過濾器卸載失敗
如果對象已經被銷毀或事件過濾器並未被正確卸載,則安裝事件過濾器會產生異常。應該在Widget被銷毀前手動卸載事件過濾器。

    CustomWidget *widget = new CustomWidget();
    QWidget *button = new QPushButton();
    button->installEventFilter(widget);
    // 在程序退出前,手動卸載事件過濾器
    button->removeEventFilter(widget); 

2、過濾的事件類型錯誤
在事件過濾器中,只能處理特定類型的事件。如果過濾事件類型錯誤,將會導致程序異常退出。應該在實現過濾器函數時,先判斷事件類型是否匹配。

    bool CustomWidget::eventFilter(QObject *obj, QEvent *event)
    {
        if (event->type() == QEvent::KeyPress && obj == button) { // 該事件過濾器處理某個push button對象的按鍵事件
            QKeyEvent *keyEvent = static_cast(event);
            if (keyEvent->key() == Qt::Key_Delete) { // 只處理某個按鍵事件
                // 在此處理刪除事件
                return true;
            }
        }
        return QWidget::eventFilter(obj, event);
    }

三、installeventfilter(this)選取

1、多個對象使用同一個事件過濾器
在處理多個對象的相同事件時,可以為這些對象安裝同一個事件過濾器。這時可以使用this作為事件過濾器,因為在對象內部,this實際上就是這個對象的地址。這樣可以簡化代碼,提高程序效率。

    QLineEdit *line1 = new QLineEdit();
    QLineEdit *line2 = new QLineEdit();
    QLineEdit *line3 = new QLineEdit();
    // 三個QLineEdit共用一個事件過濾器
    line1->installEventFilter(this);
    line2->installEventFilter(this);
    line3->installEventFilter(this);
    
    bool CustomWidget::eventFilter(QObject *obj, QEvent *event)
    {
        if (event->type() == QEvent::FocusIn && obj == line1) { // 該事件過濾器處理多個LineEdit對象的獲取焦點事件
            // 在此處理焦點事件
            return QWidget::eventFilter(obj, event);
        } else if (event->type() == QEvent::FocusIn && obj == line2) {
            // 在此處理焦點事件
            return QWidget::eventFilter(obj, event);
        } else if (event->type() == QEvent::FocusIn && obj == line3) {
            // 在此處理焦點事件
            return QWidget::eventFilter(obj, event);
        }
        return QWidget::eventFilter(obj, event);
    }

2、給子對象安裝事件過濾器
在父對象中,給所有子對象安裝同一個事件過濾器也可以使用this作為事件過濾器。這樣可以減少代碼量,提高程序效率。

    CustomWidget::CustomWidget(QWidget *parent)
        : QWidget(parent)
    {
        QLineEdit *line1 = new QLineEdit();
        QLineEdit *line2 = new QLineEdit();
        QLineEdit *line3 = new QLineEdit();
        // 所有LineEdit共用一個事件過濾器
        line1->installEventFilter(this);
        line2->installEventFilter(this);
        line3->installEventFilter(this);
    }   

四、installeventfilter的使用示例

    // 為一個QLabel安裝事件過濾器,當該QLabel滑鼠移動時,在狀態欄顯示該位置的坐標
    class CustomWidget : public QWidget
    {
        Q_OBJECT
    
    public:
        explicit CustomWidget(QWidget *parent = nullptr);
    
    protected:
        bool eventFilter(QObject *obj, QEvent *event) override;
    
    private:
        QLabel *label;
        QStatusBar *statusBar;
    };
    
    CustomWidget::CustomWidget(QWidget *parent)
        : QWidget(parent)
    {
        label = new QLabel("Label");
        statusBar = new QStatusBar();
        QHBoxLayout *layout = new QHBoxLayout();
        layout->addWidget(label);
        setLayout(layout);
        setStatusBar(statusBar);
    
        label->installEventFilter(this); // 為label安裝事件過濾器
    }
    
    bool CustomWidget::eventFilter(QObject *obj, QEvent *event)
    {
        if (obj == label && event->type() == QEvent::MouseMove) { // 該事件過濾器處理QLabel滑鼠移動事件
            QMouseEvent *mouseEvent = static_cast(event);
            QString status = QString("坐標:%1,%2").arg(mouseEvent->pos().x()).arg(mouseEvent->pos().y());
            statusBar->showMessage(status);
        }
        return QWidget::eventFilter(obj, event);
    }

原創文章,作者:FYLQ,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/146694.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
FYLQ的頭像FYLQ
上一篇 2024-10-31 15:32
下一篇 2024-10-31 15:32

相關推薦

  • 抖音外放親媽下葬事件的背後真相

    近期,一段抖音外放親媽下葬的視頻引發廣泛關注和熱議。不少人對這個事件感到震驚和憤怒,認為這種行為非常不尊重親人,觸犯了社會公德和家庭道德。但是,事情真相到底是什麼呢?我們有必要從多…

    編程 2025-04-28
  • cc.director.on事件監聽器

    本文將從多個方面詳細介紹Cocos Creator中的cc.director.on事件監聽器。 一、cc.director.on的作用和用法 cc.director.on是Coco…

    編程 2025-04-27
  • JavaScript點擊事件全方位指南

    一、click事件基礎 click事件是最常用的滑鼠事件之一,當元素被單擊時觸發。click事件適用於大多數HTML元素(<a>、<button>)和SVG…

    編程 2025-04-25
  • 詳解JavaScript onclick事件

    一、onclick的基礎知識 onclick事件是JavaScript中最常用的事件之一,它在用戶點擊某個HTML元素時觸發。通常我們可以通過給元素添加一個onclick屬性來綁定…

    編程 2025-04-25
  • 探究keyup和keydown事件

    一、介紹 在前端開發中,代碼執行通常與用戶操作有關。用戶操作中,常用的是鍵盤事件,其中keydown和keyup事件是最為常見的兩種。這兩種事件都可以用來監測用戶按鍵,但它們有不同…

    編程 2025-04-25
  • CSS 事件穿透

    在 Web 開發中,CSS 負責網頁的樣式,而 JavaScript 負責網頁的行為。雖然兩者有不同的職責,但在實際的開發過程中,我們經常會遇到將二者結合起來的場景。比如需要通過 …

    編程 2025-04-25
  • Spring Boot Filter過濾器

    Spring Boot是當前非常流行的Java Web開發框架,它提供了一個非常方便的方式來創建和運行Web應用程序。相比於傳統的Java EE應用程序,它更加簡單易用、依賴性更少…

    編程 2025-04-25
  • onclick事件詳解

    實現交互功能是Web開發的重要部分,而onclick事件就是其中一個最常用的交互事件之一。在本文中,我們將從多個角度對onclick事件進行詳細闡述。 一、使用onclick事件實…

    編程 2025-04-24
  • 布谷鳥過濾器詳解

    布谷鳥過濾器是一種高效的數據結構,主要用於判斷一個元素是否存在於一個集合中。它基於哈希表實現,以空間換時間,具有優秀的時間和空間複雜度。本文將從應用場景、原理、實現方式、優缺點等多…

    編程 2025-04-24
  • 事件驅動模型

    一、事件驅動模型一般分為幾部分 事件驅動模型一般分為三部分: 1.事件源 2.事件對象 3.事件監聽器 事件源是指事件發起的對象,事件對象是指事件的具體內容,事件監聽器是用於處理事…

    編程 2025-04-24

發表回復

登錄後才能評論