国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Qt開發(fā)-鼠標事件

這篇具有很好參考價值的文章主要介紹了Qt開發(fā)-鼠標事件。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

引言

個人認為,事件機制是Qt最難以理解且最為精妙的一部分。事件主要分為兩種:

  1. 在與用戶交互時發(fā)生。比如按下鼠標(mousePressEvent),敲擊鍵盤(keyPressEvent)等。

  1. 系統(tǒng)自動發(fā)生,比如計時器事件(timerEvent)等。

在發(fā)生事件時(比如說上面說的按下鼠標),就會產(chǎn)生一個QEvent對象(這里是QMouseEvent,為QEvent的子類),這個QEvent對象會傳給當前組件的event函數(shù)。如果當前組件沒有安裝事件過濾器(這個后面會提到),則會被event函數(shù)發(fā)放到相應的xxxEvent函數(shù)中(這里是mousePressEvent函數(shù))。

需要區(qū)分的是:事件與信號并不相同。

比如:鼠標單擊按鈕,鼠標事件(QMouseEvent),而按鈕本身發(fā)射clicked()信號。一般而言我們只需要關注單擊信號,不用考慮鼠標事件。但是當我們要對該按鈕做額外操作,不想通過信號處理,此時事件就是一個很好的選擇。關閉事件(QCloseEvent)是一個常用的事件。


一,事件

Qt 中所有事件類都繼承于 QEvent。在事件對象創(chuàng)建完畢后,Qt 將這個事件對象傳遞給 QObject 的 event()函數(shù)。event()函數(shù)并不直接處理事件,而是按照事件對象的類型分派給特定的事件處理函數(shù)(eventhandler)。

Qt開發(fā)-鼠標事件

信號是通過connect()來綁定槽函數(shù)處理響應,那么事件是怎么處理的呢?

處理事件有5種常用的方法:

  1. 重新實現(xiàn)部件的paintEvent()、mousePressEvent()等事件處理函數(shù)。這是最常用的一種方法,不過只能用來處理特定部件的特定事件(即需要新建類去實現(xiàn))

  1. 重新實現(xiàn)notify()函數(shù)。這個函數(shù)的功能強大,提供了完全的控制,可以再事件過濾器得到事件之間就獲得他們。但是,它一次只能處理一個事件。

  1. 向QApplication對象上安裝事件過濾器。因為一個程序只有一個QApplication對象,實現(xiàn)的功能和notify()函數(shù)相同,優(yōu)點是可以同時處理多個事件。

  1. 重新實現(xiàn)event()函數(shù)。QObject類的event()函數(shù)可以在事件達到默認事件處理函數(shù)之前獲得該事件。

  1. 在對象上安裝事件過濾器。使用事件過濾器可以再一個界面類中同時處理不同子部件的事件(在本類中實現(xiàn))

實際編程中最常用的是方法(1),其次是方法(5)。方法2要繼承QApplication類,方法3需要全局的事件過濾器,減緩事件的傳遞。

鼠標事件:

常用的鼠標事件:(本篇處理事件用的是方法一:重寫鼠標事件)

  • void mousePressEvent(QMouseEvent *event); //單擊

  • void mouseReleaseEvent(QMouseEvent *event); //釋放

  • void mouseDoubleClickEvent(QMouseEvent *event); //雙擊

  • void mouseMoveEvent(QMouseEvent *event); //移動

  • void wheelEvent(QWheelEvent *event); //滑輪

鼠標事件使用的時候,加頭文件: #include <QMouseEvent>

重寫事件框架:

1??鼠標按下事件

void Widget::mousePressEvent(QMouseEvent *event)
{
    // 如果是鼠標左鍵按下   
    if(event->button() == Qt::LeftButton){
        ···
    }
    // 如果是鼠標右鍵按下
    else if(event->button() == Qt::RightButton){
       ···
    }
}

2??鼠標移動事件

void Widget::mouseMoveEvent(QMouseEvent *event)
{
    // 這里必須使用buttons()
    if(event->buttons() & Qt::LeftButton){  //進行的按位與
       ···
    }
}

默認情況下,觸發(fā)事件需要點擊一下,才能觸發(fā)??稍O置為自動觸發(fā):setMouseTracking(true);

3??鼠標釋放事件

void Widget::mouseReleaseEvent(QMouseEvent *event)
{
   ···
}

4??鼠標雙擊事件

void Widget::mouseDoubleClickEvent(QMouseEvent *event)
{
    // 如果是鼠標左鍵按下
    if(event->button() == Qt::LeftButton){
      
        ···
    }
}

5??滾輪事件

void Widget::wheelEvent(QWheelEvent *event)
{
    // 當滾輪遠離使用者時
    if(event->delta() > 0){
        ···
    }else{//當滾輪向使用者方向旋轉時
        ···
    }
}

實例演示(在label控件中,移動鼠標獲取實時位置,并顯示在界面上)

  • 創(chuàng)建mylabel類,基類設置為QLabel

Qt開發(fā)-鼠標事件

這里用了類似自定義控件的方法,對Mylabel類進行封裝。設置基類QLabel 是為了在ui界面中提升label控件(即將label控件和Mylabel關聯(lián),提升時候必須二者基類相同)

  • 在mylabel.h中聲明鼠標事件

#pragma once
#include <qlabel.h>

class mylabel : public QLabel
{
public:
    mylabel(QWidget* parent = 0);
    ~mylabel();
public:
    //鼠標移動事件
    void mouseMoveEvent(QMouseEvent* event);
    //鼠標按下事件
    void mousePressEvent(QMouseEvent* event);
    //鼠標釋放事件
    void mouseReleaseEvent(QMouseEvent* event);
};
  • 在mylabel.cpp中重寫事件

#include "mylabel.h"
#include"QMouseEvent"


mylabel::mylabel(QWidget* parent) :QLabel(parent)
{
    
}
mylabel::~mylabel()
{

}
//鼠標移動顯示坐標
void mylabel::mouseMoveEvent(QMouseEvent* event)
{
    if (event->buttons() & Qt::LeftButton)  //進行的按位與(只有左鍵點擊移動才滿足)
    { 
        QString str = QString("Move:(X:%1,Y:%2)").arg(event->x()).arg(event->y());
         this->setText(str);
         
    }
    
}
//鼠標按下顯示“ok,mouse is press”
void mylabel::mousePressEvent(QMouseEvent* event)
{
    setText("Ok, mouse is press");

}
//鼠標釋放清除顯示
void mylabel::mouseReleaseEvent(QMouseEvent* event)
{
    setText(" ");
}
  • 在主函數(shù)(QTest.cpp)中聲明mylabel的類對象(即聲明一個mylabel類的label控件)

#include "qtest.h"

QTest::QTest(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
    //聲明mylabel類的控件
    mylabel* label1 = new mylabel(this);
    label1->setGeometry(QRect(130, 100, 271, 161));
    //設置邊框
    label1->setFrameShape(QFrame::Panel);
}
Qt開發(fā)-鼠標事件

另外,當調(diào)用setMouseTracking(true);時(即設置鼠標狀態(tài)為自動觸發(fā)),需要將鼠標移動事件的if語句去掉(因為不需要點擊觸發(fā)了)

修改maylabel.cpp事件:

#include "mylabel.h"
#include"QMouseEvent"


mylabel::mylabel(QWidget* parent) :QLabel(parent)
{
    //設置鼠標狀態(tài)(自動觸發(fā))
    setMouseTracking(true);
}
mylabel::~mylabel()
{

}
//鼠標移動顯示坐標
void mylabel::mouseMoveEvent(QMouseEvent* event)
{
   QString str = QString("Move:(X:%1,Y:%2)").arg(event->x()).arg(event->y());
   this->setText(str);
}
//鼠標按下顯示“ok,mouse is press”
void mylabel::mousePressEvent(QMouseEvent* event)
{
    setText("Ok, mouse is press");

}
//鼠標釋放清除顯示
void mylabel::mouseReleaseEvent(QMouseEvent* event)
{
    setText(" ");
}

效果展示:

Qt開發(fā)-鼠標事件

??這里用的是代碼創(chuàng)建label控件,那么能不能用ui界面編輯然后在對label控件提升呢?

答案是可以的,但是需要注意的是:此處不能選擇全局包含

Qt開發(fā)-鼠標事件

否則會出現(xiàn):

Qt開發(fā)-鼠標事件

我想其中的原因主要是因為:

本實例是新建了一個mylabel類,而不是像QT常用控件(三)——自定義控件封裝 - 唯有自己強大 - 博客園 (cnblogs.com)這篇博文中直接新添加了一個設計師界面類(即包含ui .h .cpp)。當選擇全局包含時,就包含了主類。

其實也有解決的辦法:需要在提升界面的頭文件處,將工程目錄下自定義控件的地址放于此處(本篇地址:C:/Users/WFD/Desktop/QTest/QTest/mylabel.h)

Qt開發(fā)-鼠標事件

二,事件的分發(fā):event函數(shù)

上面提到的xxxEvent函數(shù),稱為事件處理器(event handler)。而event函數(shù)的作用就在于事件的分發(fā)。如果想在事件的分發(fā)之前就進行一些操作,比如監(jiān)聽(阻塞)鼠標按下事件。

如果希望在事件分發(fā)之前做一些操作,就可以重寫這個 event()函數(shù)了。比如我們希望阻塞鼠標按下事件,那么我們就在新建的Mylabel類中重寫event()函數(shù)(該類的父類是QLabel)

  • 在Mylabel.h中聲明event事件

#include"qlabel.h"
class Mylabel : public QLabel
{
public:
    explicit Mylabel(QWidget* parent = 0);

    //鼠標按下事件
    void mousePressEvent(QMouseEvent* event); 
    //鼠標釋放事件
    void mouseReleaseEvent(QMouseEvent* event);
    //聲明event事件
    bool event(QEvent* e);
};
  • 在Mylabel.cpp中重寫event事件。

#include "Mylabel.h"
#include"QMouseEvent"

Mylabel::Mylabel(QWidget* parent) :QLabel(parent)
{

}

//重寫鼠標按下事件
void Mylabel::mousePressEvent(QMouseEvent* event)
{
    this->setText(QString("mouse is press x:%1,y:%2").arg(event->x()).arg(event->y()));
}
//重寫鼠標釋放事件
void Mylabel::mouseReleaseEvent(QMouseEvent* event)
{
    this->setText("mouse is release ");
}
//重寫event事件
bool Mylabel::event(QEvent* e)
{
    //如果鼠標按下,再事件分發(fā)中做攔截
    if (e->type()==QEvent::MouseButtonPress)
    {
        //靜態(tài)轉換(將QEvent的對象轉換為QMouseEvent對象)
        QMouseEvent* event = static_cast<QMouseEvent*>(e);
        this->setText(QString("event mouse is press x:%1,y:%2").arg(event->x()).arg(event->y()));
        return true;//返回ture,說明用戶自己處理事件,不往下分發(fā)(即攔截上面的按下事件)
    }
    return QLabel::event(e);
}
Qt開發(fā)-鼠標事件

點擊鼠標可以看到,觸發(fā)的是event的事件(即阻塞了mousePressEvent的事件)。特別需要注意的是:在將不需要阻塞分發(fā)的時候,需要分發(fā)給父類的event函數(shù)處理。即(return QLable::event(e);)

由此可以見,event()是一個集中處理不同類型的事件的地方。如果你不想重寫一大堆事件處理器,就可以重寫這個 event()函數(shù),通過 QEvent::type()判斷不同的事件。鑒于重寫 event()函數(shù)需要十分小心注意父類的同名函數(shù)的調(diào)用,一不留神就可能出現(xiàn)問題,所以一般還是建議只重寫事件處理器(當然,也必須記得是不是應該調(diào)用父類的同名處理器)。

三,事件過濾器(Even Filter)

某些應用場景下,需要攔截某個組件發(fā)生的事件,讓這個事件不再向其他組件進行傳播,這時候可以為這個組件或其父組件安裝一個事件過濾器,該過濾器在event分發(fā)之前進行攔截。

事件的過濾有兩個步驟:

1??對QObject組件安裝過濾器(調(diào)用installEvenFilter函數(shù))

void QObject::installEventFilter ( QObject * filterObj );

參數(shù)filterobj 是指誰為組件安裝過濾器(一般是父類)

  • 這個函數(shù)接受一個 QObject *類型的參數(shù)。記得剛剛我們說的,eventFilter()函數(shù)是 QObject 的一個成員函數(shù),因此,任意 QObject 都可以作為事件過濾器(問題在于,如果你沒有重寫 eventFilter()函數(shù),這個事件過濾器是沒有任何作用的,因為默認什么都不會過濾)。已經(jīng)存在的過濾器則可以通過QObject::removeEventFilter()函數(shù)移除。

  • 我們可以向一個對象上面安裝多個事件處理器 ,只要調(diào)用多次installEventFilter()函數(shù)。如果一個對象存在多個事件過濾器,那么,最后一個安裝的會第一個執(zhí)行,也就是后進先執(zhí)行的順序。

2??事件過濾器的重寫(evenFilter函數(shù))

virtual bool QObject::eventFilter ( QObject * watched, QEvent * event );

可以看到,函數(shù)有兩個參數(shù),一個為具體發(fā)生事件的組件,一個為發(fā)生的事件(產(chǎn)生的QEvent對象)。當事件是我們感興趣的類型,可以就地進行處理,并令其不再轉發(fā)給其他組件。函數(shù)的返回值也是bool類型,作用跟even函數(shù)類似,返回true為不再轉發(fā),false則讓其繼續(xù)被處理。

實例:通過事件過濾器阻塞上面代碼中的鼠標按下事件

#include "qtest.h"
#include"qmouseevent"

QTest::QTest(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
    //第一步:給label添加過濾器
    ui.label->installEventFilter(this);


}
//第二步:重寫過濾事件
bool QTest::eventFilter(QObject* obj, QEvent* e)
{
    if (obj == ui.label)
    {
        //如果鼠標按下,再事件分發(fā)中做攔截
        if (e->type() == QEvent::MouseButtonPress)
        {
            QMouseEvent* event = static_cast<QMouseEvent*>(e);
            ui.label->setText(QString("eventfilter mouse is press x:%1,y:%2").arg(event->x()).arg(event->y()));
            return true;//返回ture,說明用戶自己處理事件,不往下分發(fā)(即攔截上面的按下事件)
        }
    }
    return QWidget::eventFilter(obj, e);
}

//重寫鼠標按下事件
void QTest::mousePressEvent(QMouseEvent* event)
{
    ui.label->setText(QString("mouse is press x:%1,y:%2").arg(event->x()).arg(event->y()));
}

//重寫事件分發(fā)
bool QTest::event(QEvent* e)
{
    //如果鼠標按下,再事件分發(fā)中做攔截
    if (e->type() == QEvent::MouseButtonPress)
    {
        QMouseEvent* event = static_cast<QMouseEvent*>(e);
        ui.label->setText(QString("event mouse is press x:%1,y:%2").arg(event->x()).arg(event->y()));
        return true;//返回ture,說明用戶自己處理事件,不往下分發(fā)(即攔截上面的按下事件)
    }
    return QWidget::event(e);
}

運行結果:

Qt開發(fā)-鼠標事件

可以看到在過濾器事件中就監(jiān)聽了鼠標按壓(即阻塞了后面的事件分發(fā)和鼠標按壓)文章來源地址http://www.zghlxwxcb.cn/news/detail-488670.html

到了這里,關于Qt開發(fā)-鼠標事件的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • [QT/C++]如何得知鼠標事件是由觸摸事件轉換而來的,使得鼠標觸摸事件分離

    依據(jù)來源:https://doc.qt.io/qt-5/qml-qtquick-mouseevent.html 具體是在event事件或者mouse系列事件中捕獲到鼠標事件后,用如下代碼判斷鼠標事件是否由觸摸事件轉換而來的 通過該條件的一律返回,剩下的就是不由觸摸事件生成的鼠標事件,由此做到鼠標與觸摸事件的分離,使得觸摸事

    2024年02月13日
    瀏覽(27)
  • qt鼠標事件

    鼠標移動事件,只要移動鼠標,就會觸發(fā)這個函數(shù),其中,正常情況下,只有當鼠標在QWidget界面點擊鼠標后,才會捕捉到鼠標的坐標,那如何實現(xiàn),在不點擊鼠標的情況下,也可以捕捉到鼠標移動事件呢? 代碼如下: 比如在主窗口QWidget下有一個父窗口Lable,在鼠標進入Lab

    2024年02月09日
    瀏覽(29)
  • Qt5鼠標事件

    判斷鼠標按下了哪個鍵 本文福利, 莬 費領取Qt開發(fā)學習資料包、技術視頻,內(nèi)容包括(C++語言基礎,Qt編程入門,QT信號與槽機制,QT界面開發(fā)-圖像繪制,QT網(wǎng)絡,QT數(shù)據(jù)庫編程,QT項目實戰(zhàn),QSS,OpenCV,Quick模塊,面試題等等)↓↓↓↓↓↓見下面↓↓文章底部點擊 莬 費領取

    2024年02月12日
    瀏覽(23)
  • Qt 鼠標進入離開事件

    QEvent::Enter ? 鼠標進入事件,當鼠標進入到窗口/控件內(nèi)部時,觸發(fā)該事件,它對應的子類是 QEnterEvent QEvent::Leave ? 鼠標離開事件,當鼠標離開到窗口/控件內(nèi)部時,觸發(fā)該事件 自定義一個標簽控件 LabelX ,讓它繼承自 QLabel ,然后重寫父類的 enterEvent 和 leaveEvent 。 代碼如下:

    2024年01月24日
    瀏覽(25)
  • 【QT】鼠標常用事件

    【QT】鼠標常用事件

    新建項目 加標簽控件 當鼠標進去,顯示【鼠標進入】,離開時顯示【鼠標離開】 將QLable提升成自己的控件,然后再去捕獲 添加文件 改繼承的類名 提升類 同一個父類,可以提升 效果 現(xiàn)在代碼就和Qlabel對應起來了。 在.h中聲明,.cpp中實現(xiàn) 測試 鼠標的移動、按下、松開事件

    2024年02月06日
    瀏覽(20)
  • qt鼠標常用事件

    qt鼠標常用事件

    和上一個案例相同,也是做了提升,換了相同父類,但是方式有所不同 先在widget.ui中加入label標簽,此時其父類為QLabel,然后想實現(xiàn)鼠標在QLabel上的捕獲。所以我們需要把QLabel提升為自己的框架,然后自定義框架后,我們就可以自己捕獲信息了。然后添加新文件mylabel.h和mylabel.cpp,

    2024年02月02日
    瀏覽(21)
  • qt 禁止點擊 屏蔽鼠標事件

    我開了一個線程上傳文件夾,用一個進度條顯示進度 測試 就在界面隨便點擊 ,也沒有出泵任何控件,沒有引發(fā)槽函數(shù),直接就崩了! 不知道為什么崩了,所以直接禁止點擊,蔽鼠標事件! 主界面 進度條 Qt::WidgetAttribute::WA_TransparentForMouseEvents 該屬性的含義是“透明掉鼠標事

    2024年02月15日
    瀏覽(23)
  • QT的使用3:鼠標事件

    QT的使用3:鼠標事件

    用戶對界面中的控件進行操作后,控件需要進行響應,響應一般有兩種方式,一種是之前學過的槽函數(shù),另一種是事件,部分操作無法通過槽函數(shù)響應,只能通過事件,例如鼠標移動,鍵盤輸入等。 當某個事件(鼠標、鍵盤)發(fā)生的時候,相關控件就會收到這個事件,并且調(diào)

    2024年02月13日
    瀏覽(20)
  • QT學習日記12——Qt中的鼠標事件

    QT學習日記12——Qt中的鼠標事件

    學習視頻鏈接 最新QT從入門到實戰(zhàn)完整版|傳智教育_嗶哩嗶哩_bilibili https://www.bilibili.com/video/BV1g4411H78N?p=31vd_source=0471cde1c644648fafd07b54e303c905 目錄 一、鼠標進入和出去事件 1.1 新建 C++ 文件 1.2 編寫代碼 1.3 操作 1.4 運行結果 二、鼠標點擊、釋放和移動事件 2.1 修改代碼 2.2 運行結

    2024年02月11日
    瀏覽(21)
  • Qt鼠標點擊事件處理:顯示鼠標點擊位置(完整示例)

    Qt鼠標點擊事件處理:顯示鼠標點擊位置(完整示例)

    Qt 入門實戰(zhàn)教程(目錄) 前驅(qū)文章: Qt Creator 創(chuàng)建 Qt 默認窗口程序(推薦) 事件是對各種應用程序需要知道的由應用程序內(nèi)部或者外部產(chǎn)生的事情或者動作的通稱。 例如點擊鼠標,按下按鍵。 在Qt中使用一個對象來表示一個事件,它繼承自QEvent類。 如鼠標事件(例如點擊

    2024年02月10日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包