UI到底是怎么接受事件的事件
本文中主要講述QT中關于時間機制的一些看法:
事件的產生過程:
1 首先由底層的硬件中斷 à 操作系統(產生一個事件在其自己的事件隊列中)
2 Qt中有一個 a.exec() 會幫我們建立一個事件循環 該循環一直在等在系統有事件傳入
下列是一些示例代碼:
While(不為空隊列)
{
If(是退出事件?)
{
該APP退出;
}
If(分配事件到事件的函數;)
{執行函數};
}
具體的說,a.exec()會啟動 event loop 實際上是啟動的的是QEventLoop相關的函數:
Qt's main event loop (QCoreApplication::exec()) fetches native window system events from the event queue, translates them into QEvents, and sends the translated events to QObjects.
Qt中的事件處理函數:
1 bool event(QEvent* ev);
該函數是Qt中所有事件進來后執行的第一個函數;
在源碼中 該函數的實現過程大致為:
bool event(QEvent* ev)
{
swtich(ev->type())
{
Case QEvent::MouseButtonPress: mousePressEvent(ev);break;
Case QEvent::KeyPress: keyPressEvent(ev);break;
…
}
}
2 特定的事件處理函數:
void mousePressEvent(QMouseEvent *event);//鼠標點擊
void keyPressEvent(QKeyEvent *event);//鍵盤點擊
void wheelEvent(QWheelEvent *event);//鼠標滾輪
(PS:我們如何查詢 特定事件呢?
比如說我們現在是繼承的QWidget 那么我們在man手冊中查 QWidget,并在其中 搜索 event關鍵字)
3 事件過濾處理器(意義:讓事件發生后 在執行默認的事件處理函數的時候,也會執行我們所寫的事件處理函數。我們把這個事件處理函數叫事件過濾處理器)
步驟:
a 書寫事件過濾處理器
bool eventFilter(QObject *obj, QEvent *event);
//param1 obj :事件的執行者 param2:事件的類型
b 安裝 à 誰想用我們事件過濾處理器,那么誰安裝
(PS: 事件過濾處理器的返回值是bool通常情況下 有事件處理的話返回true沒有的話 返回false。在后 我們還是要調取一下父類的事件過濾器
return 父類::eventFilter(obj, event);)
4事件過濾處理器的特殊使用
給QApplication安裝事件過濾處理器(有什么好處呢?當事件傳入到本APP的時候 ,不單單會執行傳統的事件處理函數,還會執行我們的事件過濾處理器<全部的事件,全部的控件>)
5 notify()函數 (了解qApp->notify(ui->textEdit,keyevent);的用法)
While(processEvent())
{
If(是退出事件?)
{
該APP退出;
}
If(notify())
{event()};
}
事件的發出:
事件的發出大概分兩種情況:
1 硬件產生的(硬件在操作)
2 軟件產生的(模擬硬件操作)
我們現在研究一下 如何軟件產生事件:
a. post方法 post方法會直接將事件發送到 event loop //異步的
QKeyEvent *keyevent = new QKeyEvent(QEvent::KeyPress, Qt::Key_A + i,Qt::NoModifier);
//postEvent 發送事件 param1:發出者 param2:發出的事件
QCoreApplication::postEvent(this,keyevent);
b. send方法send方法會直接將事件發送的具體的個體 //同步的
QKeyEvent *keyevent = new QKeyEvent(QEvent::KeyPress, Qt::Key_A + i,Qt::NoModifier);
//sendEvent 發送事件 param1:發送到誰 param2:發送的事件 //同步的
// QCoreApplication::sendEvent(ui->textEdit,keyevent);
(PS:我們也可以使用qApp->notify(ui->textEdit,keyevent); 來達到 send的效果)
(PS:對于事件的傳遞:
總體規則 :一個在某一個控件上發生的事件,那么它肯定會執行它的事件處理函數,如果該事件處理函數中對event進行了 accept 那么該事件不在向父控件傳遞;如果該事件處理函數中對event進行了 ignore 那么該事件繼續向父控件傳遞;
默認情況下 ,我們是對event進行了 accept;