W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
前面說了幾個標(biāo)準(zhǔn)對話框,下面不打算繼續(xù)說明一些組件的使用,因為這些使用很難講完,很多東西都是與實際應(yīng)用相關(guān)的。實際應(yīng)用的復(fù)雜性決定了我們根本不可能把所有組件的所有使用方法都說明白。這次來說說 Qt 相對高級一點的特性:事件。
事件(event)是有系統(tǒng)或者 Qt 本身在不同的時刻發(fā)出的。當(dāng)用戶按下鼠標(biāo),敲下鍵盤,或者是窗口需要重新繪制的時候,都會發(fā)出一個相應(yīng)的事件。一些事件是在對用戶操作做出響應(yīng)的時候發(fā)出,如鍵盤事件等;另一些事件則是由系統(tǒng)自動發(fā)出,如計時器事件。
一般來說,使用 Qt 編程時,我們并不會把主要精力放在事件上,因為在 Qt 中,需要我們關(guān)心的事件總會發(fā)出一個信號。比如,我們關(guān)心的是 QPushButton 的鼠標(biāo)點擊,但我們不需要關(guān)心這個鼠標(biāo)點擊事件,而是關(guān)心它的 clicked()信號。這與其他的一些框架不同:在 Swing 中,你所要關(guān)心的是JButton 的 ActionListener 這個點擊事件。
Qt 的事件很容易和信號槽混淆。這里簡單的說明一下,signal 由具體對象發(fā)出,然后會馬上交給由connect 函數(shù)連接的 slot 進(jìn)行處理;而對于事件,Qt 使用一個事件隊列對所有發(fā)出的事件進(jìn)行維護(hù),當(dāng)新的事件產(chǎn)生時,會被追加到事件隊列的尾部,前一個事件完成后,取出后面的事件進(jìn)行處理。但是,必要的時候,Qt 的事件也是可以不進(jìn)入事件隊列,而是直接處理的。并且,事件還可以使用“事件過濾器”進(jìn)行過濾??偟膩碚f,如果我們使用組件,我們關(guān)心的是信號槽;如果我們自定義組件,我們關(guān)心的是事件。因為我們可以通過事件來改變組件的默認(rèn)操作。比如,如果我們要自定義一個 QPushButton,那么我們就需要重寫它的鼠標(biāo)點擊事件和鍵盤處理事件,并且在恰當(dāng)?shù)臅r候發(fā)出 clicked()信號。
還記得我們在 main 函數(shù)里面創(chuàng)建了一個 QApplication 對象,然后調(diào)用了它的 exec()函數(shù)嗎?其實,這個函數(shù)就是開始 Qt 的事件循環(huán)。在執(zhí)行 exec()函數(shù)之后,程序?qū)⑦M(jìn)入事件循環(huán)來監(jiān)聽?wèi)?yīng)用程序的事件。當(dāng)事件發(fā)生時,Qt 將創(chuàng)建一個事件對象。Qt 的所有事件都繼承于 QEvent 類。在事件對象創(chuàng)建完畢后,Qt 將這個事件對象傳遞給 QObject 的 event()函數(shù)。event()函數(shù)并不直接處理事件,而是按照事件對象的類型分派給特定的事件處理函數(shù)(event handler)。關(guān)于這一點,我們會在以后的章節(jié)中詳細(xì)說明。
在所有組件的父類 QWidget 中,定義了很多事件處理函數(shù),如 keyPressEvent()、keyReleaseEvent()、mouseDoubleClickEvent()、mouseMoveEvent ()、mousePressEvent()、mouseReleaseEvent()等。這些函數(shù)都是 protected virtual 的,也就是說,我們應(yīng)該在子類中重定義這些函數(shù)。下面來看一個例子。
#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QMouseEvent>
class EventLabel : public QLabel
{
protected:
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
};
void EventLabel::mouseMoveEvent(QMouseEvent *event)
{
this->setText(QString("<center><h1>Move: (%1, %2)</h1></center>")
.arg(QString::number(event->x()), QString::number(event->y())));
}
void EventLabel::mousePressEvent(QMouseEvent *event)
{
this->setText(QString("<center><h1>Press: (%1, %2)</h1></center>")
.arg(QString::number(event->x()), QString::number(event->y())));
}
void EventLabel::mouseReleaseEvent(QMouseEvent *event)
{
QString msg;
msg.sprintf("<center><h1>Release: (%d, %d)</h1></center>",
event->x(), event->y());
this->setText(msg);
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
EventLabel *label = new EventLabel;
label->setWindowTitle("MouseEvent Demo");
label->resize(300, 200);
label->show();
return app.exec();
}
這里我們繼承了 QLabel 類,重寫了 mousePressEvent、mouseMoveEvent 和 MouseReleaseEvent 三個函數(shù)。我們并沒有添加什么功能,只是在鼠標(biāo)按下(press)、鼠標(biāo)移動(move)和鼠標(biāo)釋放(release)時把坐標(biāo)顯示在這個 Label 上面。注意我們在 mouseReleaseEvent 函數(shù)里面有關(guān) QString 的構(gòu)造。我們沒有使用 arg 參數(shù)的方式,而是使用 C 語言風(fēng)格的 sprintf 來構(gòu)造 QString 對象,如果你對 C 語法很熟悉(估計很多 C++程序員都會比較熟悉的吧),那么就可以在 Qt 中試試熟悉的 C 格式化寫法啦!
本文出自 “豆子空間” 博客,請務(wù)必保留此出處 http://devbean.blog.51cto.com/448512/194031
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: