程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> Qt事件處理器和事件過濾器實例

Qt事件處理器和事件過濾器實例

編輯:C++入門知識

   在上一篇中我們了解了Qt中事件處理的方式,也提到了最常用的就是使用事件處理器和事件過濾器這兩種方法。在這一篇,我們就來看看事件處理器和事件過濾器是怎麼使用的。

一、事件處理器使用實例
       Qt中針對每一種常見的事件類型都提供了相應的事件處理器,我們如果想捕獲某種類型的事件並進行自定義處理,那麼只需要實現重寫這些事件處理器就行,至於常見的時間類型和對應的事件處理器如下圖:

        在我的程序中,我使用到了鼠標滾輪事件,主要實現的就效果就是大家比較熟悉的:用一個控件顯示圖片,當滾動鼠標滾輪的時候可以調整圖片顯示的大小。
        這裡我要做的就是捕獲該圖片顯示控件的鼠標滾輪事件,然後改寫該控件的鼠標滾輪滾動事件處理器。
        首先我們來看看鼠標滾輪事件以及相應的事件處理器是啥,查看上面的圖即可知道:

        在Qt幫助文檔裡面我們可以查看到如下語句“The event handler QWidget::wheelEvent() receives wheel events.”。也就是說最後事件處理器會調用wheelEvent()函數來處理該事件,因此我們需要的就是改寫wheelEvent()這個函數。

第一步:在頭文件中申明該函數:

 


第二步實現wheelEvent()函數(這裡主要關注的是事件處理的框架,而不是具體的示例,因此不去過多講解代碼細節):

[cpp]
<span style="font-size:16px;">void ImageWidget::wheelEvent(QWheelEvent *event) 

    int numDegrees = event->delta(); 
    int num = numDegrees / 120; 
    if(num < 0) 
    { 
        num = 0 - num; 
    } 
 
    if (event->orientation() == Qt::Horizontal) { 
 
        //scrollHorizontally(numSteps);  
        scale *= 1.25; 
        resize(this->scale * this->size()); 
    } else { 
        //scrollVertically(numSteps);  
        if(numDegrees > 0) 
        { 
            //scale *= 0.75;  
            resize(num * 0.75 * this->size()); 
        } 
        else if(numDegrees < 0) 
        { 
            //scale *= 1.25;  
            resize(num * 1.25 * this->size()); 
        } 
    } 
 
    event->accept(); 
}</span> 
<span style="font-size:16px;">void ImageWidget::wheelEvent(QWheelEvent *event)
{
    int numDegrees = event->delta();
    int num = numDegrees / 120;
    if(num < 0)
    {
        num = 0 - num;
    }

    if (event->orientation() == Qt::Horizontal) {

        //scrollHorizontally(numSteps);
        scale *= 1.25;
        resize(this->scale * this->size());
    } else {
        //scrollVertically(numSteps);
        if(numDegrees > 0)
        {
            //scale *= 0.75;
            resize(num * 0.75 * this->size());
        }
        else if(numDegrees < 0)
        {
            //scale *= 1.25;
            resize(num * 1.25 * this->size());
        }
    }

    event->accept();
}</span>
        到這裡這個功能就實現了,大家看看上面的頭文件就知道這裡還實現了其它類型事件的處理,其實都是一樣的思路,找到欲處理的事件類型,找到對應的事件處理器,重寫事件處理器中處理事件的方法即可。


二、事件過濾器使用實例
        Qt事件模型中一項非常強大的功能就是一個QObject實例可以監視另一個QObject實例中的事件,實現方法是在目標對象中安裝事件過濾器。這裡我們接著上面的實例進行,為上面的圖片浏覽器增加一個功能:在我的程序中設置了一個自動播放的按鍵,點擊按鍵後,在圖片顯示部件中就會顯示一系列圖片,就像動畫播放許多幅圖片一樣,當在上面點擊鼠標左鍵時,就停止動畫播放而是停留在當前播放的圖片;當我再點擊鼠標右鍵的時候,又恢復為動畫播放模式。
        首先說一下主要的頁面布局:我在一個QMainWindow中放置一個自定義的圖片顯示部件。對照上面的說明,我們很容易知道,實現該功能的方法就是在目標部件(自定義的圖片顯示部件)上注冊事件過濾器,此時的事件過濾器就是我們所說的監視對象,完成這些步驟之後,當目標部件有事件產生後,首先會傳遞給監視對象(事件過濾器)進行處理而不是該事件對應的事件處理器。所以說我們可以截獲事件進行處理。監視對象截獲目標對象的事件後就會調用自己的eventFilter()函數處理這些事件。
總結起來就兩個步驟:
第一:對目標對象調用installEventFilter()來注冊監視對象(事件過濾器);
第二:重寫監視對象的eventFilter()函數處理目標對象的事件。
我們就嚴格按照這兩步走:
首先使用installEventFilter()函數給目標對象注冊事件監聽器:


[cpp]
<span style="font-size:16px;">//給圖片顯示部件注冊事件過濾器  
imageWidget->installEventFilter(this);</span> 
<span style="font-size:16px;">//給圖片顯示部件注冊事件過濾器
imageWidget->installEventFilter(this);</span>
然後就是重寫監視對象eventFilter()函數:


[cpp] \
<span style="font-size:16px;">//圖片顯示部件時間過濾器處理  
bool PMainWindow::eventFilter(QObject *target, QEvent *event) 

    if(target == imageWidget) 
    { 
        qDebug("The imageWidget generate the event!"); 
        if(event->type() == QEvent::MouseButtonPress) 
        { 
            QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event); 
            if(mouseEvent->buttons() & Qt::LeftButton) 
            { 
                qDebug("The Left Button Event!"); 
                killTimer(timeId); 
            } 
            else if(mouseEvent->buttons() & Qt::RightButton) 
            { 
                qDebug("The Right Button Event!"); 
 
                //clickNum++;  
                //again();  
                timeId = startTimer(3000); 
            } 
 
            return true; 
        } 
    } 
 
    //其它部件產生的事件則交給基類處理  
    return QMainWindow::eventFilter(target, event); 
}</span> 

 作者:chenlong12580
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved