第七章 事件處理器

nikola_zhou發表於2018-08-29

 

1.一般情況下,在使用視窗部件得時候,訊號是十分有用的,而在實現視窗部件得時候事件則是十分有用的,所以不要把兩者搞混了。

 

2.Qt處理的時間型別有一百多種,其中每一種都可以通過一個列舉值進行識別。

 

3.通過QKeyEvent::modifiers()可以檢測修飾鍵(Ctrl,Shift,Alt等):

 

if(event->modifiers() & Qt::ContorlModifier)

do something........;

4.實現按鍵繫結可以採用QAction:

 

QAction* newAction = new QAction(tr("do something "), this);

newAction->setShortcut(tr("Home"));

connect(newAction,SIGNAL(activated()),this,SLOT(fun()));

 

那麼Home鍵就於fun繫結上了。

 

5.QAction::setShortcutContext()和QShortcut::setContext()可以配置快捷鍵的響應策略;

 

6.定時器事件也是較為常用的事件型別,定時器事件允許應用程式可以在一定時間間隔後執行事件處理。比如一些滾動字幕什麼的。

 

7.Qt事件模型一個非常強大的功能是QObject是咧在看到它自己的事件之前,可以通過設定另外一個QObject實列先監視這些事件。

 

舉個栗子:比如你有很多個QLineEdit然後你想對這些控制元件做一些特別的事情,比如按下空格後focus移動到下一個控制元件。當然你可以通過重寫QLineEdit中的 keyPressEvent()來實現:

 

if(event->key() == Qt::Key_space)

{

focusNextChild();

}

 

這樣做很簡單,但是當出現多種型別的控制元件的時候,比如還有一堆QPusbutton,QSpinBox也希望做出如上的操作的時候,就需要每個空間都去重寫函式。顯得麻煩。找個時候,你可以通過監視這些空間中的事件,並在監視中實現所需的行為,其中包含兩個步驟:

1.通過installEventFilter()註冊監視物件。

2.在監視物件的eventFilter()函式中處理目標物件的事件

 

 

 

lineEdit1->installEventFilter(this);

lineEdit2->installEventFilter(this);

button1->installEventFilter(this);

button2->installEventFilter(this);

 

一旦註冊,傳送給這幾個控制元件的事件就會在它們到達目的地之前先傳送給this的evenFilter()

 

if(target == lineEdit1||target == lineEdit2 ||target == button1||target == button2)

{

if(event->type() == QEvent::Press)

{

QKeyEvent* e = static_cast<QKeyEvent*>(event)

if(e->key() == Qt:key_Space)

{

focusNextChild();

}

}

}

 

當呼叫QApplication::exec()時,就啟動了Qt事件迴圈,在開始的時候,Qt會發出一些事件命令來顯示和繪製視窗部件。在這之後,事件迴圈就開始執行。它不斷的檢查是否有事件發生並且把這些事件傳送給應用程式中的QObject.

當處理一個事件的時候,也可能會同時產生一些其他的事件並會將其追加到Qt的事件佇列中。如果在處理一個特定的事件上耗費的事件過多,那麼就會 讓介面無法響應。解決這種情況的辦法有兩個,一個是採用多執行緒(這個過段時間再寫)。一個是不停的呼叫preocessEvents()。這個函式告訴Qt處理所有那些還沒被處理的各類事件(並且也處理當下做的事件),然後再將控制權返還給呼叫者。

 

e.g 你想讀個檔案,這個檔案很大,如果這個在主執行緒中,無疑會阻塞執行緒,介面會卡死。於是可以這樣

 

for(int i = 0;i< row;++i)

{

for(int j= 0;j<col;++j)

{

out << quint16(row)<<quint16(col);

 

}

qApp->processEvents();

}

但是這樣有個問題,如果你正在讀檔案的時候,又點了一次讀檔案怎麼辦?這可能也會產生很多奇怪的問題。於是可以這樣:

for(int i = 0;i< row;++i)

{

for(int j= 0;j<col;++j)

{

out << quint16(row)<<quint16(col);

 

}

qApp->processEvents(QEvent::ExculdeUserInputEvents);

}

 

告訴Qt,這個時候忽略滑鼠和鍵盤事件。

 

 

相關文章