有沒有catia做幕墻的網(wǎng)站色目人
事件系統(tǒng)的概述
事件的類型
Qt 支持多種事件類型,每種類型代表不同的用戶交互或系統(tǒng)事件。常見的事件類型包括:
- 輸入事件:如鼠標(biāo)事件(QMouseEvent)、鍵盤事件(QKeyEvent)。
- 窗口事件:如窗口大小變化事件(QResizeEvent)、窗口關(guān)閉事件(QCloseEvent)。
- 定時(shí)器事件:如定時(shí)器超時(shí)事件(QTimerEvent)。
- 繪圖事件:如繪圖事件(QPaintEvent)。
- 自定義事件:可以通過繼承 QEvent 類創(chuàng)建自定義事件。
QEvent 類
QEvent 類是所有事件的基類。每個(gè)事件類型都繼承自 QEvent 并擴(kuò)展了特定的功能。常見的事件類型及其子類有:
- QMouseEvent:處理鼠標(biāo)相關(guān)事件,如鼠標(biāo)點(diǎn)擊、移動(dòng)、釋放等。
- QKeyEvent:處理鍵盤輸入事件,如按鍵按下和釋放。
- QResizeEvent:處理窗口大小變化事件。
- QCloseEvent:處理窗口關(guān)閉事件。
- QPaintEvent:處理繪圖事件。
- QTimerEvent:處理定時(shí)器超時(shí)事件。
自定義事件
可以創(chuàng)建自定義事件類型,通過繼承 QEvent 類并定義自己的數(shù)據(jù)和處理邏輯。
class MyCustomEvent : public QEvent {
public:
static const QEvent::Type MyEventType = static_cast<QEvent::Type>(QEvent::User + 1);MyCustomEvent() : QEvent(MyEventType) {}// 自定義數(shù)據(jù)和方法
QString message;
};
事件處理機(jī)制
事件處理函數(shù)(event handlers)
每個(gè) QWidget 子類都有一個(gè) event() 方法,它處理所有傳遞給該對(duì)象的事件。Qt 提供了特定類型事件的處理函數(shù),例如 mousePressEvent()、keyPressEvent() 等。這些特定的處理函數(shù)通常在 event() 函數(shù)中被調(diào)用。
void MyWidget::mousePressEvent(QMouseEvent *event) {if (event->button() == Qt::LeftButton) {// 處理鼠標(biāo)左鍵按下事件}
}
信號(hào)與槽機(jī)制
信號(hào)與槽機(jī)制是 Qt 的核心特性之一,它提供了一種對(duì)象之間通信的方式,非常適合用于實(shí)現(xiàn)觀察者模式。
信號(hào)
信號(hào)是由對(duì)象在特定情況下發(fā)出的消息。例如,當(dāng)按鈕被點(diǎn)擊時(shí),QPushButton 對(duì)象會(huì)發(fā)出 clicked() 信號(hào)。
槽
槽是一個(gè)可以被信號(hào)連接的函數(shù)。當(dāng)信號(hào)被發(fā)出時(shí),所有連接到該信號(hào)的槽都會(huì)被調(diào)用。槽可以是任意的成員函數(shù)、靜態(tài)函數(shù),甚至是 lambda 表達(dá)式。
連接信號(hào)與槽
使用 QObject::connect() 方法將信號(hào)連接到槽:
connect(button, &QPushButton::clicked, this, &MyWidget::onButtonClicked);void MyWidget::onButtonClicked() {// 處理按鈕點(diǎn)擊事件
}
事件傳遞和處理過程
事件循環(huán)
事件循環(huán)是 Qt 應(yīng)用程序的核心部分。它負(fù)責(zé)調(diào)度和分發(fā)事件,使得應(yīng)用程序能夠響應(yīng)用戶輸入和其他事件。
Qt 應(yīng)用程序的事件循環(huán)由 QCoreApplication::exec() 方法啟動(dòng)。該方法進(jìn)入一個(gè)無限循環(huán),等待事件發(fā)生,并將其分發(fā)到合適的處理函數(shù)。
int main(int argc, char *argv[]) {QApplication app(argc, argv);MyWidget w;w.show();return app.exec();
}
事件在父子窗口之間的傳遞遵循對(duì)象的層次結(jié)構(gòu)。以下是詳細(xì)的過程:
事件生成:
- 事件(如鼠標(biāo)點(diǎn)擊、鍵盤輸入等)由操作系統(tǒng)或 Qt 自身生成,并加入事件隊(duì)列。
事件分發(fā):
- QCoreApplication::notify 將事件分發(fā)給目標(biāo)對(duì)象(子窗口或父窗口)。
事件過濾器:
- 在 event() 函數(shù)中,事件首先傳遞給事件過濾器。如果事件過濾器處理了事件,則事件傳遞過程結(jié)束。
子窗口處理事件:
- 如果事件首先傳遞給子窗口,子窗口的 event() 函數(shù)會(huì)嘗試處理該事件。如果子窗口處理了該事件,則事件傳遞過程結(jié)束。
傳遞給父窗口:
- 如果子窗口未處理該事件,事件會(huì)傳遞給父窗口。父窗口的 event() 函數(shù)會(huì)嘗試處理該事件,或者進(jìn)一步傳遞給父窗口的事件過濾器。
逐層傳遞:
- 這一過程會(huì)逐層向上,直到事件被處理或到達(dá)頂層窗口(即沒有父窗口的窗口)。
notify 函數(shù)
notify 函數(shù)是事件傳遞的核心,它在事件循環(huán)中被調(diào)用,用于將事件分發(fā)到相應(yīng)的對(duì)象。
bool QCoreApplication::notify(QObject *receiver, QEvent *event) {if (receiver == nullptr) {qWarning("QCoreApplication::notify: Unexpected null receiver");return false;}// Before delivering the event, we pass it through the event filtersif (receiver->isWidgetType() && static_cast<QWidget*>(receiver)->testAttribute(Qt::WA_SetCursor)) {// Special handling for widgets with set cursor attribute}// Call the event filtersif (receiver->d_func()->sendThroughObjectEventFilters(receiver, event)) {return true;}// Deliver the eventreturn receiver->event(event);
}
在 notify 函數(shù)中,事件傳遞過程如下:
事件過濾器:
- 首先,事件被傳遞給目標(biāo)對(duì)象的事件過濾器。
- 通過 sendThroughObjectEventFilters 方法調(diào)用所有安裝在目標(biāo)對(duì)象上的事件過濾器。
- 如果任何一個(gè)事件過濾器處理了事件并返回 true,事件傳遞過程就會(huì)終止,notify 返回 true。
事件分發(fā):
- 如果事件過濾器沒有處理事件,則調(diào)用目標(biāo)對(duì)象的 event 函數(shù)。
- 具體的事件處理函數(shù)(如 mousePressEvent、keyPressEvent 等)在 event 函數(shù)內(nèi)部被調(diào)用。
事件過濾器filter
事件過濾器允許對(duì)象在事件到達(dá)其目標(biāo)對(duì)象之前對(duì)其進(jìn)行攔截和處理。事件傳遞過程中,事件過濾器是一個(gè)重要的環(huán)節(jié)。通過在父窗口上安裝事件過濾器,可以攔截和處理傳遞給子窗口的事件。
class MyFilter : public QObject {
Q_OBJECT
protected:
bool eventFilter(QObject *obj, QEvent *event) override {if (event->type() == QEvent::MouseButtonPress) {// 處理鼠標(biāo)按下事件qDebug() << "Mouse button pressed in object:" << obj;return true; // 事件已被處理,不再傳遞}return QObject::eventFilter(obj, event); // 傳遞給默認(rèn)處理程序
}
};// 在父窗口上安裝事件過濾器
MyFilter *filter = new MyFilter;
parentWidget->installEventFilter(filter);
event() 函數(shù)處理
每個(gè) QWidget 都有一個(gè) event() 函數(shù),它處理傳遞給這個(gè)窗口部件的所有事件。這個(gè)函數(shù)會(huì)根據(jù)事件的類型調(diào)用相應(yīng)的事件處理函數(shù)。
bool QWidget::event(QEvent *event) {switch (event->type()) {case QEvent::MouseButtonPress:mousePressEvent(static_cast<QMouseEvent *>(event));break;case QEvent::KeyPress:keyPressEvent(static_cast<QKeyEvent *>(event));break;// 處理其他事件類型default:return QObject::event(event);}return true;
}
事件處理函數(shù)Handler
事件處理函數(shù)是用戶能夠控制的的,最底層的事件處理流程,Qt默認(rèn)實(shí)現(xiàn)了很多事件處理函數(shù),用戶可以在子類重寫這些事件處理函數(shù)。
處理鼠標(biāo)事件
通過重載 mousePressEvent 方法處理鼠標(biāo)點(diǎn)擊事件。
void MyWidget::mousePressEvent(QMouseEvent *event) {if (event->button() == Qt::LeftButton) {qDebug() << "Left mouse button pressed at" << event->pos();}
}
處理鍵盤事件
通過重載 keyPressEvent 方法處理鍵盤按鍵事件。
void MyWidget::keyPressEvent(QKeyEvent *event) {if (event->key() == Qt::Key_Escape) {qDebug() << "Escape key pressed";close(); // 關(guān)閉窗口}
}
總結(jié)
在 Qt 中,事件在父子窗口之間的傳遞和處理過程遵循對(duì)象的層次結(jié)構(gòu),通過 notify 函數(shù)、事件過濾器和 event() 函數(shù)進(jìn)行管理。事件可以從子窗口傳遞到父窗口,也可以在父窗口中攔截和處理,確保事件能夠在適當(dāng)?shù)牡胤奖徽_處理。