中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

濟南網(wǎng)站優(yōu)化技術(shù)廠家全球疫情最新數(shù)據(jù)

濟南網(wǎng)站優(yōu)化技術(shù)廠家,全球疫情最新數(shù)據(jù),少兒編程官網(wǎng),做免費資料分享網(wǎng)站會不會涉及版權(quán)目錄 事件分發(fā)函數(shù) 無邊框窗口拖動 自定義事件 發(fā)送事件的函數(shù) 自定義事件 系統(tǒng)定義的事件號 自定義事件號 自定義事件類 發(fā)送和處理事件 sendEvent與postEvent的區(qū)別 棧區(qū)對象 堆區(qū)對象 事件傳播機制 事件傳播的過程 事件傳播到父組件 鼠標單擊事件與按鈕單擊信…

目錄

事件分發(fā)函數(shù)

無邊框窗口拖動

自定義事件

發(fā)送事件的函數(shù)

自定義事件

系統(tǒng)定義的事件號

自定義事件號

自定義事件類

發(fā)送和處理事件

sendEvent與postEvent的區(qū)別

棧區(qū)對象

堆區(qū)對象

事件傳播機制

事件傳播的過程

事件傳播到父組件

鼠標單擊事件與按鈕單擊信號的關(guān)聯(lián)

事件過濾

無邊框窗口拖動(事件過濾器實現(xiàn))

事件跟信號的區(qū)別


事件分發(fā)函數(shù)

傳遞事件的通常方式是調(diào)用虛函數(shù)。例如,QMouseEvent通過調(diào)用QWidget::mousePressEvent()來傳遞。這個虛函數(shù)負責進行適當?shù)捻憫?yīng),通常是處理鼠標點擊,并發(fā)出對應(yīng)的信號。如果在虛函數(shù)的實現(xiàn)中不執(zhí)行所有必要的工作,則可能需要調(diào)用基類的實現(xiàn)。

如果希望替換基類的事件處理函數(shù),則必須自己實現(xiàn)所有內(nèi)容。但是,如果您只想擴展基類的功能,那么您可以實現(xiàn)您想要的功能,并調(diào)用基類來獲得您不想處理的任何情況的默認行為。

有時,沒有這樣一個特定于事件的函數(shù),或者特定于事件的函數(shù)是不夠的。最常見的例子是按Tab鍵。通常情況下,QWidget會攔截這些來移動鍵盤焦點,但也有一些小部件本身需要Tab鍵。

這些對象可以重新實現(xiàn)QObject::event()(通用事件處理程序),并在通常處理之前或之后執(zhí)行它們的事件處理,或者它們可以完全替換函數(shù)。一個非常不尋常的小部件既解釋Tab又具有特定于應(yīng)用程序的自定義事件,它可能包含以下event()函數(shù):

bool Widget::event(QEvent* ev)override
{//如果是按鍵按下事件if (ev->type() == QEvent::Type::KeyPress){QKeyEvent* ke = static_cast<QKeyEvent*>(ev);if (ke->key() == Qt::Key::Key_Tab){//對tab鍵按下進行處理qInfo() << "處理 tab 按鍵...";return true;    //返回true表示此事件已經(jīng)處理了,不會繼續(xù)傳播}}// 調(diào)用父類實現(xiàn)處理其它的事件return QWidget::event(ev);
}

注意:對于所有未處理的情況,仍然調(diào)用QWidget::event(),并且返回值指示是否處理了事件;true值防止事件被發(fā)送到其他對象。返回true表示此事件已經(jīng)處理了,不需要再處理了。

無邊框窗口拖動

使用事件分發(fā)函數(shù)實現(xiàn)無邊框窗口的拖動

bool event(QEvent* ev)override
{if (ev->type() == QEvent::MouseButtonPress){auto me = static_cast<QMouseEvent*>(ev);pressPos = me->pos();return true;}else if (ev->type() == QEvent::MouseMove){auto me = static_cast<QMouseEvent*>(ev);//如果鼠標左鍵是按下的if(me->buttons() & Qt::MouseButton::LeftButton)this->move(me->globalPosition().toPoint() - pressPos);return true;}return QWidget::event(ev);
}

自定義事件

發(fā)送事件的函數(shù)

許多應(yīng)用程序都希望創(chuàng)建和發(fā)送它們自己的事件。通過構(gòu)造合適的事件對象并使用QCoreApplication::sendEvent()和QCoreApplication::postEvent()發(fā)送事件,您可以以與Qt自己的事件循環(huán)完全相同的方式發(fā)送事件。

sendEvent()立即處理事件。當它返回時,事件過濾器和/或?qū)ο蟊旧硪呀?jīng)處理了該事件。對于許多事件類,都有一個名為isAccepted()的函數(shù),它告訴您事件是被最后一個調(diào)用的處理程序接受還是拒絕的。

postEvent()將事件發(fā)送到隊列中,以便稍后進行分派。下次Qt的主事件循環(huán)運行時,它會分發(fā)所有發(fā)布的事件,并進行一些優(yōu)化。例如,如果有幾個調(diào)整大小事件,它們將被壓縮為一個。同樣適用于繪制事件:QWidget::update()調(diào)用postEvent(),它通過避免多次重繪來消除閃爍并提高速度。

自定義事件

要創(chuàng)建自定義類型的事件,需要定義一個事件號,該事件號必須大于等于QEvent::User,并且可能需要繼承QEvent的子類,以便傳遞關(guān)于自定義事件的特定信息。有關(guān)更多詳細信息,請參閱QEvent文檔。

系統(tǒng)定義的事件號

QEvent::Type?這個枚舉類型定義了Qt中有效的事件類型。事件類型和每個類型的專門類如下:

常量值(value)描述
QEvent::None0不是一個事件
QEvent::ActionAdded114一個新 action 被添加(QActionEvent)
QEvent::ActionChanged113一個 action 被改變(QActionEvent)
QEvent::ActionRemoved115一個 action 被移除(QActionEvent)
QEvent::ActivationChange99Widget 的頂層窗口激活狀態(tài)發(fā)生了變化
QEvent::ApplicationActivate121這個枚舉已被棄用,使用 ApplicationStateChange 代替
QEvent::ApplicationActivatedApplicationActivate這個枚舉已被棄用,使用 ApplicationStateChange 代替
QEvent::ApplicationDeactivate122這個枚舉已被棄用,使用 ApplicationStateChange 代替
QEvent::ApplicationFontChange36應(yīng)用程序的默認字體發(fā)生了變化
QEvent::ApplicationLayoutDirectionChange37應(yīng)用程序的默認布局方向發(fā)生了變化
QEvent::ApplicationPaletteChange38應(yīng)用程序的默認調(diào)色板發(fā)生了變化
QEvent::ApplicationStateChange214應(yīng)用程序的狀態(tài)發(fā)生了變化
QEvent::ApplicationWindowIconChange35應(yīng)用程序的圖標發(fā)生了變化
QEvent::ChildAdded68一個對象獲得孩子(QChildEvent)
QEvent::ChildPolished69一個部件的孩子被拋光(QChildEvent)
QEvent::ChildRemoved71一個對象時區(qū)孩子(QChildEvent)
QEvent::Clipboard40剪貼板的內(nèi)容發(fā)生改變
QEvent::Close19Widget 被關(guān)閉(QCloseEvent)
QEvent::CloseSoftwareInputPanel200一個部件要關(guān)閉軟件輸入面板(SIP)
QEvent::ContentsRectChange178部件內(nèi)容區(qū)域的外邊距發(fā)生改變
QEvent::ContextMenu82上下文彈出菜單(QContextMenuEvent)
QEvent::CursorChange183部件的鼠標發(fā)生改變
QEvent::DeferredDelete52對象被清除后將被刪除(QDeferredDeleteEvent)
QEvent::DragEnter60在拖放操作期間鼠標進入窗口部件(QDragEnterEvent)
QEvent::DragLeave62在拖放操作期間鼠標離開窗口部件(QDragLeaveEvent)
QEvent::DragMove61拖放操作正在進行(QDragMoveEvent)
QEvent::Drop63拖放操作完成(QDropEvent)
QEvent::DynamicPropertyChange170動態(tài)屬性已添加、更改或從對象中刪除
QEvent::EnabledChange98部件的 enabled 狀態(tài)已更改
QEvent::Enter10鼠標進入部件的邊界(QEnterEvent)
QEvent::EnterEditFocus150編輯部件獲得焦點進行編輯,必須定義 QT_KEYPAD_NAVIGATION
QEvent::EnterWhatsThisMode124當應(yīng)用程序進入“What’s This?”模式,發(fā)送到 toplevel 頂層部件
QEvent::Expose206當其屏幕上的內(nèi)容無效,發(fā)送到窗口,并需要從后臺存儲刷新
QEvent::FileOpen116文件打開請求(QFileOpenEvent)
QEvent::FocusIn8部件或窗口獲得鍵盤焦點(QFocusEvent)
QEvent::FocusOut9部件或窗口失去鍵盤焦點(QFocusEvent)
QEvent::FocusAboutToChange23部件或窗口焦點即將改變(QFocusEvent)
QEvent::FontChange97部件的字體發(fā)生改變
QEvent::Gesture198觸發(fā)了一個手勢(QGestureEvent)
QEvent::GestureOverride202觸發(fā)了手勢覆蓋(QGestureEvent)
QEvent::GrabKeyboard188Item 獲得鍵盤抓取(僅限 QGraphicsItem)
QEvent::GrabMouse186項目獲得鼠標抓取(僅限 QGraphicsItem)
QEvent::GraphicsSceneContextMenu159在圖形場景上的上下文彈出菜單(QGraphicsScene ContextMenuEvent)
QEvent::GraphicsSceneDragEnter164在拖放操作期間,鼠標進入圖形場景(QGraphicsSceneDragDropEvent)
QEvent::GraphicsSceneDragLeave166在拖放操作期間鼠標離開圖形場景(QGraphicsSceneDragDropEvent)
QEvent::GraphicsSceneDragMove165在場景上正在進行拖放操作(QGraphicsSceneDragDropEvent)
QEvent::GraphicsSceneDrop167在場景上完成拖放操作(QGraphicsSceneDragDropEvent)
QEvent::GraphicsSceneHelp163用戶請求圖形場景的幫助(QHelpEvent)
QEvent::GraphicsSceneHoverEnter160鼠標進入圖形場景中的懸停項(QGraphicsSceneHoverEvent)
QEvent::GraphicsSceneHoverLeave162鼠標離開圖形場景中一個懸停項(QGraphicsSceneHoverEvent)
QEvent::GraphicsSceneHoverMove161鼠標在圖形場景中的懸停項內(nèi)移動(QGraphicsSceneHoverEvent)
QEvent::GraphicsSceneMouseDoubleClick158鼠標在圖形場景中再次按下(雙擊)(QGraphicsSceneMouseEvent)
QEvent::GraphicsSceneMouseMove155鼠標在圖形場景中移動(QGraphicsSceneMouseEvent)
QEvent::GraphicsSceneMousePress156鼠標在圖形場景中按下(QGraphicsSceneMouseEvent)
QEvent::GraphicsSceneMouseRelease157鼠標在圖形場景中釋放(QGraphicsSceneMouseEvent)
QEvent::GraphicsSceneMove182部件被移動(QGraphicsSceneMoveEvent)
QEvent::GraphicsSceneResize181部件已調(diào)整大小(QGraphicsSceneResizeEvent)
QEvent::GraphicsSceneWheel168鼠標滾輪在圖形場景中滾動(QGraphicsSceneWheelEvent)
QEvent::Hide18部件被隱藏(QHideEvent)
QEvent::HideToParent27子部件被隱藏(QHideEvent)
QEvent::HoverEnter127鼠標進入懸停部件(QHoverEvent)
QEvent::HoverLeave128鼠標留離開懸停部件(QHoverEvent)
QEvent::HoverMove129鼠標在懸停部件內(nèi)移動(QHoverEvent)
QEvent::IconDrag96窗口的主圖標被拖走(QIconDragEvent)
QEvent::IconTextChange101部件的圖標文本發(fā)生改變(已棄用)
QEvent::InputMethod83正在使用輸入法(QInputMethodEvent)
QEvent::InputMethodQuery207輸入法查詢事件(QInputMethodQueryEvent)
QEvent::KeyboardLayoutChange169鍵盤布局已更改
QEvent::KeyPress6鍵盤按下(QKeyEvent)
QEvent::KeyRelease7鍵盤釋放(QKeyEvent)
QEvent::LanguageChange89應(yīng)用程序翻譯發(fā)生改變
QEvent::LayoutDirectionChange90布局的方向發(fā)生改變
QEvent::LayoutRequest76部件的布局需要重做
QEvent::Leave11鼠標離開部件的邊界
QEvent::LeaveEditFocus151編輯部件失去編輯的焦點,必須定義 QT_KEYPAD_NAVIGATION
QEvent::LeaveWhatsThisMode125當應(yīng)用程序離開“What’s This?”模式,發(fā)送到頂層部件
QEvent::LocaleChange88系統(tǒng)區(qū)域設(shè)置發(fā)生改變
QEvent::NonClientAreaMouseButtonDblClick176鼠標雙擊發(fā)生在客戶端區(qū)域外
QEvent::NonClientAreaMouseButtonPress174鼠標按鈕按下發(fā)生在客戶端區(qū)域外
QEvent::NonClientAreaMouseButtonRelease175鼠標按鈕釋放發(fā)生在客戶端區(qū)域外
QEvent::NonClientAreaMouseMove173鼠標移動發(fā)生在客戶區(qū)域外
QEvent::MacSizeChange177用戶更改了部件的大小(僅限 OS X)
QEvent::MetaCall43通過 QMetaObject::invokeMethod() 調(diào)用異步方法
QEvent::ModifiedChange102部件修改狀態(tài)發(fā)生改變
QEvent::MouseButtonDblClick4鼠標再次按下(QMouseEvent)
QEvent::MouseButtonPress2鼠標按下(QMouseEvent)
QEvent::MouseButtonRelease3鼠標釋放(QMouseEvent)
QEvent::MouseMove5鼠標移動(QMouseEvent)
QEvent::MouseTrackingChange109鼠標跟蹤狀態(tài)發(fā)生改變
QEvent::Move13部件的位置發(fā)生改變(QMoveEvent)
QEvent::NativeGesture197系統(tǒng)檢測到手勢(QNativeGestureEvent)
QEvent::OrientationChange208屏幕方向發(fā)生改變(QScreenOrientationChangeEvent)
QEvent::Paint12需要屏幕更新(QPaintEvent)
QEvent::PaletteChange39部件的調(diào)色板發(fā)生改變
QEvent::ParentAboutToChange131部件的 parent 將要更改
QEvent::ParentChange21部件的 parent 發(fā)生改變
QEvent::PlatformPanel212請求一個特定于平臺的面板
QEvent::PlatformSurface217原生平臺表面已創(chuàng)建或即將被銷毀(QPlatformSurfaceEvent)
QEvent::Polish75部件被拋光
QEvent::PolishRequest74部件應(yīng)該被拋光
QEvent::QueryWhatsThis123如果部件有“What’s This?”幫助,應(yīng)該接受事件
QEvent::ReadOnlyChange106部件的 read-only 狀態(tài)發(fā)生改變
QEvent::RequestSoftwareInputPanel199部件想要打開軟件輸入面板(SIP)
QEvent::Resize14部件的大小發(fā)生改變(QResizeEvent)
QEvent::ScrollPrepare204對象需要填充它的幾何信息(QScrollPrepareEvent)
QEvent::Scroll205對象需要滾動到提供的位置(QScrollEvent)
QEvent::Shortcut117快捷鍵處理(QShortcutEvent)
QEvent::ShortcutOverride51按下按鍵,用于覆蓋快捷鍵(QKeyEvent)
QEvent::Show17部件顯示在屏幕上(QShowEvent)
QEvent::ShowToParent26子部件被顯示
QEvent::SockAct50Socket 激活,用于實現(xiàn) QSocketNotifier
QEvent::StateMachineSignal192信號被傳遞到狀態(tài)機(QStateMachine::SignalEvent)
QEvent::StateMachineWrapped193事件是一個包裝器,用于包含另一個事件(QStateMachine::WrappedEvent)
QEvent::StatusTip112狀態(tài)提示請求(QStatusTipEvent)
QEvent::StyleChange100部件的樣式發(fā)生改變
QEvent::TabletMove87Wacom 寫字板移動(QTabletEvent)
QEvent::TabletPress92Wacom 寫字板按下(QTabletEvent)
QEvent::TabletRelease93Wacom 寫字板釋放(QTabletEvent)
QEvent::OkRequest94Ok 按鈕在裝飾前被按下,僅支持 Windows CE
QEvent::TabletEnterProximity171Wacom 寫字板進入接近事件(QTabletEvent),發(fā)送到 QApplication
QEvent::TabletLeaveProximity172Wacom 寫字板離開接近事件(QTabletEvent),發(fā)送到 QApplication
QEvent::ThreadChange22對象被移動到另一個線程。這是發(fā)送到此對象的最后一個事件在上一個線程中,參見:QObject::moveToThread()
QEvent::Timer1定時器事件(QTimerEvent)
QEvent::ToolBarChange120工具欄按鈕在 OS X 上進行切換
QEvent::ToolTip110一個 tooltip 請求(QHelpEvent)
QEvent::ToolTipChange184部件的 tooltip 發(fā)生改變
QEvent::TouchBegin194觸摸屏或軌跡板事件序列的開始(QTouchEvent)
QEvent::TouchCancel209取消觸摸事件序列(QTouchEvent)
QEvent::TouchEnd196觸摸事件序列結(jié)束(QTouchEvent)
QEvent::TouchUpdate195觸摸屏事件(QTouchEvent)
QEvent::UngrabKeyboard189Item 失去鍵盤抓取(QGraphicsItem)
QEvent::UngrabMouse187Item 失去鼠標抓取(QGraphicsItem、QQuickItem)
QEvent::UpdateLater78部件應(yīng)該排隊在以后重新繪制
QEvent::UpdateRequest77部件應(yīng)該被重繪
QEvent::WhatsThis111部件應(yīng)該顯示“What’s This”幫助(QHelpEvent)
QEvent::WhatsThisClicked118部件的“What’s This”幫助鏈接被點擊
QEvent::Wheel31鼠標滾輪滾動(QWheelEvent)
QEvent::WinEventAct132發(fā)生了 Windows 特定的激活事件
QEvent::WindowActivate24窗口已激活
QEvent::WindowBlocked103窗口被模態(tài)對話框阻塞
QEvent::WindowDeactivate25窗戶被停用
QEvent::WindowIconChange34窗口的圖標發(fā)生改變
QEvent::WindowStateChange105窗口的狀態(tài)(最小化、最大化或全屏)發(fā)生改變(QWindowStateChangeEvent)
QEvent::WindowTitleChange33窗口的標題發(fā)生改變
QEvent::WindowUnblocked104一個模態(tài)對話框退出后,窗口將不被阻塞
QEvent::WinIdChange203本地窗口的系統(tǒng)標識符發(fā)生改變
QEvent::ZOrderChange126部件的 z 值發(fā)生了改變,該事件不會發(fā)送給頂層窗口

用戶事件的值應(yīng)該介于 QEvent::User 和 QEvent::MaxUser之間。

常量描述
QEvent::User1000用戶定義的事件
QEvent::MaxUser65535最后的用戶事件 ID

為方便起見,可以使用 [static] int QEvent::registerEventType(int *hint* = -1) 函數(shù)來注冊和存儲一個自定義事件類型,這樣做會避免意外地重用一個自定義事件類型。

自定義事件號

enum EventType 
{NumberEvent = QEvent::Type::User
};

自定義事件類

// 自定義事件類
class NumberChangeEvent : public QEvent
{
public:NumberChangeEvent(int number): QEvent(QEvent::Type(NumberEvent)), m_number(number){}~NumberChangeEvent(){qInfo() << __FUNCTION__;}qint32 getNumber(){ return m_number; }
private:int m_number;
};

發(fā)送和處理事件

#include <QApplication>
#include <QWidget>
#include <QEvent>
#include <QPushButton>// 自定義事件類型
enum EventType
{NumberEvent = QEvent::Type::User
};// 自定義事件類
class NumberChangeEvent : public QEvent
{
public:NumberChangeEvent(int number): QEvent(QEvent::Type(NumberEvent)), m_number(number){}~NumberChangeEvent(){qInfo() << __FUNCTION__;}qint32 getNumber(){ return m_number; }
private:int m_number;
};// 自定義事件處理
class Widget : public QWidget
{Q_OBJECT
public:Widget(QWidget* parent = nullptr):QWidget(parent){resize(640,480);m_btn = new QPushButton("發(fā)送自定義事件", this);// 點擊按鈕發(fā)送事件connect(m_btn, &QPushButton::clicked, this, [=](){static int i = 0;NumberChangeEvent ne(i++);//qApp->sendEvent(this, &ne);QApplication::sendEvent(this, &ne);});}~Widget(){}
protected:bool event(QEvent* ev) override{if(ev->type() == QEvent::Type(NumberEvent)){auto nev = static_cast<NumberChangeEvent*>(ev);qInfo() << "Number: " << nev->getNumber();}return QWidget::event(ev);}
private:QPushButton* m_btn;
};int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();return a.exec();
}
#include "main.moc"

除了使用事件分發(fā)函數(shù)event處理自定義事件外,也可以使用customEvent處理自定義事件,它是專門用來接收自定義事件。

void customEvent(QEvent* ev) override
{if(ev->type() == EventType::NumberEvent){auto nev = static_cast<NumberChangeEvent*>(ev);qInfo() << "Number: " << nev->getNumber();}
}

sendEvent與postEvent的區(qū)別

使用棧區(qū)對象與堆區(qū)對象分別對兩種發(fā)送方式進行測試

棧區(qū)對象

connect(m_btn, &QPushButton::clicked, this, [=](){NumberChangeEvent ne1(1);QApplication::sendEvent(this, &ne1);NumberChangeEvent ne2(1);QApplication::postEvent(this, &ne2);
});

當使用postEvent發(fā)送棧區(qū)事件對象時會直接引發(fā)中斷,因為postEvent是將事件放入事件隊列中稍后處理,棧區(qū)事件對象出作用域后內(nèi)存就會被釋放,我認為這是引發(fā)中斷的原因。而使用sendEvent發(fā)送棧區(qū)事件對象不會中斷,內(nèi)存也會自己釋放(出作用域后釋放)。

堆區(qū)對象

當使用sendEvent發(fā)送堆區(qū)對象后,內(nèi)存不會被自動釋放,需要手動釋放。而使用postEvent發(fā)送堆區(qū)事件對象內(nèi)存會自動釋放,不必手動釋放。

因此,當使用棧區(qū)對象時只能使用sendEvent發(fā)送事件,使用堆區(qū)對象時,使用sendEvent發(fā)送事件之后需要手動釋放事件對象內(nèi)存,使用postEvent發(fā)送事件會自動釋放內(nèi)存。另外,使用postEvent發(fā)送事件時可以設(shè)置事件的優(yōu)先級,讓發(fā)送的事件被優(yōu)先處理。

事件傳播機制

事件傳播的過程

Qt的事件產(chǎn)生之后,不是直接傳遞給了對象的,需要經(jīng)過一系列的過程。

  1. 事件首先由Qt的ServerApplication去接收來自于外部或內(nèi)部的一些行為,鼠標點擊,鍵盤輸入,時鐘事件等,分析并決定送往對應(yīng)的對象去處理(內(nèi)部管理機制),最后會調(diào)用[virtual] bool QCoreApplication::notify ( QObject * receiver, QEvent * event ) 去處理,當然這個是虛函數(shù),你可以在子類去重新實現(xiàn)它 。

  2. 在notify(…)中,在發(fā)給對應(yīng)的接收者前,會先把消息送給QApplication。所以如果想在你界面的Widget前先處理那些事 件,那么你可以給QApplication對象installEventFilter,然后在對應(yīng)的eventFilter()里先把這些事件都給過一 遍,然后你可以過濾一些不必要事件。

  3. 如果QApplication沒有處理那些事件,然后就是交給事件接收對象了。在這個對象接收前,也可以為這對象加一個事件過濾器,同樣是 installEventFilter。

  4. 如果eventFilter沒有過濾某些事件,那么就會將事件交給接收者的event()函數(shù)(你可以根據(jù)不同類型的事件盡情處理),如果event事件在接受者處理后,也不會上傳給父類的event,否則會上傳進入父類的event。

  5. 默認event()函數(shù)根據(jù)事件類型會調(diào)用不同的事件處理函數(shù),類似mousePressEvent(),keyPressEvent()去分別處理他們。

事件傳播到父組件

當控件忽略事件時,事件會繼續(xù)往上傳播,這里的傳播是指傳播給父組件

  • QEvent有 accept()函數(shù) 和ignore()函數(shù):

    • accept():本組件處理該事件,這個事件就不會被繼續(xù)傳播給其父組件;

    • ignore():本組件不想要處理這個事件,這個事件會被繼續(xù)傳播給其父組件;

    • 值得注意的是所有的事件默認都是接受的(即不會傳遞到父組件)

  • 忽略和接受案例

?當默認接受事件時,在本組件處理之后,事件不會傳遞到父組件mousePressEvent處理。?

#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>class Button : public QPushButton
{
public:Button(const QString& text,QWidget* parent = nullptr):QPushButton(text,parent){}void mousePressEvent(QMouseEvent* ev)override{qInfo() << __FUNCTION__;//默認是接受事件的,父組件不會收到鼠標點擊事件ev->accept();//如果忽略事件,父組件就會收到鼠標點擊事件//ev->ignore();}
};class Widget : public QWidget
{Q_OBJECT
public:Widget(QWidget* parent = nullptr):QWidget(parent){resize(640,480);Button* btn = new Button("text", this);}~Widget(){}
protected:void mousePressEvent(QMouseEvent* ev)override{qInfo() << __FUNCTION__;}
};int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();return a.exec();
}
#include "main.moc"

?當忽略事件時,在本組件處理之后,事件會被傳遞到父組件mousePressEvent處理。

class Button : public QPushButton
{
public:Button(const QString& text,QWidget* parent = nullptr):QPushButton(text,parent){}void mousePressEvent(QMouseEvent* ev)override{qInfo() << __FUNCTION__;//默認是接受事件的,父組件不會收到鼠標點擊事件//ev->accept();//如果忽略事件,父組件就會收到鼠標點擊事件ev->ignore();}
};

?

  • event事件分發(fā)函數(shù)返回值的作用
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>class Button : public QPushButton
{
public:Button(const QString& text,QWidget* parent = nullptr):QPushButton(text,parent){}bool event(QEvent* ev)override{if (ev->type() == QEvent::Type::MouseButtonPress){qInfo() << __FUNCTION__;return false;	//返回false,表示我沒有處理這個事件,可以傳遞給父組件//return true;	//返回true,表示我處理了這個事件,不再繼續(xù)傳遞了}return QPushButton::event(ev);}
};class Widget : public QWidget
{Q_OBJECT
public:Widget(QWidget* parent = nullptr):QWidget(parent){resize(640,480);Button* btn = new Button("text", this);Q_UNUSED(btn)}~Widget(){}
protected:bool event(QEvent* ev)override{if (ev->type() == QEvent::Type::MouseButtonPress){qInfo() << __FUNCTION__;}return QWidget::event(ev);}
};int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();return a.exec();
}
#include "main.moc"

事件分發(fā)函數(shù)event返回false,表示本組件沒有處理這個事件,事件會被傳遞到父組件處理,返回true則表示本組件處理了這個事件,不需要再讓父組件處理了。

鼠標單擊事件與按鈕單擊信號的關(guān)聯(lián)

class Button : public QPushButton
{
public:Button(const QString& text,QWidget* parent = nullptr):QPushButton(text,parent){}void mousePressEvent(QMouseEvent* ev) override{//return QPushButton::mousePressEvent(ev);}
};Button* btn = new Button("text", this);
connect(btn, &Button::clicked, this, [](){qInfo() << "鼠標單擊";
});

?要想觸發(fā)鼠標點擊的信號與槽就必須處理鼠標按下事件

void mousePressEvent(QMouseEvent* ev) override
{return QPushButton::mousePressEvent(ev);
}

事件過濾

有的時候,對象需要查看(可能還需要攔截)傳遞給另一個對象的事件。例如,對話框通常想要過濾一些小部件的按鍵;例如,修改返回鍵處理。

QObject::installEventFilter()函數(shù)通過設(shè)置一個事件過濾器來實現(xiàn)這一點,使指定的過濾器對象在其QObject::eventFilter()函數(shù)中接收目標對象的事件。事件過濾器在目標對象處理事件之前處理事件,允許它根據(jù)需要檢查和丟棄事件??梢允褂肣Object::removeEventFilter()函數(shù)刪除現(xiàn)有的事件過濾器。

當調(diào)用過濾器對象的eventFilter()實現(xiàn)時,它可以接受或拒絕事件,并允許或拒絕對事件的進一步處理。如果所有事件過濾器都允許對事件進行進一步處理(每個返回false),則將事件發(fā)送到目標對象本身。如果其中一個停止處理(通過返回true),目標和任何后面的事件過濾器都不會看到事件。

無邊框窗口拖動(事件過濾器實現(xiàn))

class Widget : public QWidget
{Q_OBJECT
public:Widget(QWidget* parent = nullptr):QWidget(parent){resize(640, 480);setWindowFlag(Qt::WindowType::FramelessWindowHint);setMouseTracking(true);// 安裝事件過濾器this->installEventFilter(this);}bool eventFilter(QObject* object, QEvent* ev)override{auto w = qobject_cast<QWidget*>(object);if (!w)return false;if (ev->type() == QEvent::MouseButtonPress){auto me = static_cast<QMouseEvent*>(ev);pressPos = me->pos();return true;}else if (ev->type() == QEvent::MouseMove){auto me = static_cast<QMouseEvent*>(ev);if (me->buttons() & Qt::MouseButton::LeftButton)w->move(me->globalPosition().toPoint() - pressPos);// 已經(jīng)處理了,不需要再處理MouseMoveEvent事件了return true;}return QObject::eventFilter(object, ev);}
private:QPoint pressPos;
};

在自己類里面重寫eventFilter來過濾事件,但是如果我有很多個無邊框窗口,都要實現(xiàn)移動,這個方法就不太方便了??梢韵葘懸粋€拖拽控件的過濾器對象,然后哪兒需要使用,就直接加載事件過濾器對象即可。

// 無邊框窗口拖拽的事件過濾器對象
class DragWidgetFilter :public QObject
{
public:DragWidgetFilter(QObject* parent = nullptr):QObject(parent){}bool eventFilter(QObject* object,QEvent*ev)override{auto w = qobject_cast<QWidget*>(object);if (!w)return false;if (ev->type() == QEvent::MouseButtonPress){auto me = static_cast<QMouseEvent*>(ev);pressPos = me->pos();}else if (ev->type() == QEvent::MouseMove){auto me = static_cast<QMouseEvent*>(ev);if (me->buttons() & Qt::MouseButton::LeftButton)w->move(me->globalPosition().toPoint() - pressPos);}return QObject::eventFilter(object,ev);}
private:QPoint pressPos;
};class Widget : public QWidget
{Q_OBJECT
public:Widget(QWidget* parent = nullptr):QWidget(parent){resize(640, 480);setWindowFlag(Qt::WindowType::FramelessWindowHint);setMouseTracking(true);// 使用事件過濾器對象加載事件過濾器this->installEventFilter(new DragWidgetFilter(this));}
}

事件跟信號的區(qū)別

事件(QEvent)信號(SIGNAL)
與QObject的關(guān)系由具體對象進行處理由具體對象主動產(chǎn)生
對程序的影響改寫事件處理函數(shù)可能導(dǎo)致程序行為發(fā)生改變信號是否存在對應(yīng)的槽函數(shù)不會改變程序行為
兩者的聯(lián)系一般而言,信號在具體的事件處理函數(shù)中產(chǎn)生
http://www.risenshineclean.com/news/60193.html

相關(guān)文章:

  • 網(wǎng)站建設(shè)百度優(yōu)化軟文推廣營銷
  • 做網(wǎng)站選擇系統(tǒng)愛上鏈外鏈購買交易
  • 云南網(wǎng)站開發(fā)網(wǎng)絡(luò)公司前10最新足球消息
  • 日照手機網(wǎng)站建設(shè)2022最好的百度seo
  • 怎樣給一個網(wǎng)站做專題策劃谷歌seo網(wǎng)站建設(shè)
  • 高端網(wǎng)站開發(fā)找哪家好百度seo多少錢一個月
  • vue wordpress 主題seo排名優(yōu)化軟件有
  • 手機網(wǎng)站建設(shè)軟件營銷型網(wǎng)站重要特點是
  • 做惡搞圖片的網(wǎng)站海外推廣專員
  • 網(wǎng)站建設(shè)英文合同淘寶seo軟件
  • 湛江搜索引擎網(wǎng)站推廣品牌營銷策略
  • 有些網(wǎng)站突然無法訪問寧波優(yōu)化系統(tǒng)
  • 溫州大都市建設(shè)開發(fā)有限公司網(wǎng)站seo試用軟件
  • 軟裝設(shè)計素材網(wǎng)站seo網(wǎng)站排名優(yōu)化公司
  • 湖南做網(wǎng)站kaodezhu被國家禁止訪問的網(wǎng)站怎么打開
  • 網(wǎng)站備案查詢不到說明啥短網(wǎng)址生成網(wǎng)站
  • 株洲市區(qū)網(wǎng)站建設(shè)公司長春網(wǎng)站建設(shè)方案推廣
  • 做徽標的網(wǎng)站網(wǎng)絡(luò)營銷課程心得體會
  • 一級a做片性視頻網(wǎng)站鄭州百度seo網(wǎng)站優(yōu)化
  • 中山企業(yè)建站程序三只松鼠軟文范例500字
  • 智趣游戲型網(wǎng)站開發(fā)百度收錄批量查詢工具
  • 和諧校園網(wǎng)站建設(shè)企業(yè)整站seo
  • 怎樣購買網(wǎng)站程序360公司官網(wǎng)首頁
  • 汕頭好的建站網(wǎng)站杭州疫情最新消息
  • 裝修設(shè)計網(wǎng)站源碼三只松鼠的軟文范例
  • wordpress整站隱藏百度一下手機版
  • 馬云將來淘汰的十個行業(yè)網(wǎng)站建設(shè)跨境電商哪個平臺比較好
  • 哪家網(wǎng)站建設(shè)做的好百度賬號個人中心
  • 六年級做的網(wǎng)站的軟件下載互聯(lián)網(wǎng)推廣平臺有哪些公司
  • 上海網(wǎng)絡(luò)平臺網(wǎng)站建設(shè)cba排名最新排名