現在,我們來看看對話方塊(Dialog)所用的訊息孔(Slot)。
39 void FindDialog::findClicked()
40 {
41 QString text = lineEdit->text();
42 Qt::CaseSensitivity cs =
43 caseCheckBox->isChecked() ? Qt::CaseSensitive
44 : Qt::CaseInsensitive;
45 if (backwardCheckBox->isChecked()) {
46 emit findPrevious(text, cs);
47 } else {
48 emit findNext(text, cs);
49 }
50 }
51 void FindDialog::enableFindButton(const QString &text)
52 {
53 findButton->setEnabled(!text.isEmpty());
54 }
當使用這按下搜尋鈕時,findClicked()訊息孔會被呼叫。依據Search backward 選項的選擇,它會傳送findPrevious() 或是findNext() 訊息。傳送關鍵字是特別針對QT擴充的功能,需要藉由C++預載器會將它轉換成標準的C++。
當使用者改變輸入行的文字時,enableFindButton()訊息孔會被呼叫;如果有些文字在輸入行內,搜尋鈕將可以運作,如果沒有,搜尋鈕則不可運作。
這兩個訊息孔完成了這個對話方塊,我們現在可以創造main.cpp 去測試我們的FindDialog 部件(widget)。
1 #include <QApplication>
2 #include “finddialog.h”
3 int main(int argc, char *argv[])
4 {
5 QApplication app(argc, argv);
6 FindDialog *dialog = new FindDialog;
7 dialog->show();
8 return app.exec();
9 }
通常就是使用qmake來編譯程式。因為FindDialog 類別定義包含了 Q_OBJECT巨集,
為了編譯程式,通常使用qmake指令來執行。因為FindDialog類別定義包含了Q_OBJECT巨集(macro),被qmake所產生的makefile將會包含一些特殊的規則來執行moc(Qt’s meta-object compiler)
關於QT的meta-object system的介紹將在下一節中。
為了使得moc運作正確,我們必須從分離的文件中,在標頭檔裡放置類別定義。由moc所產生的這段程式碼將會包含標頭檔與自己的C++樣版碼。使用Q_OBJECT 巨集的類別雖然必須要有moc在上面執行,但這不會是問題,因為qmake會自動將必要的規則加入makefile之中。
但是,如果你忘記使用qmake重新產生你的makefile,moc 會變得無法執行;連結器(Linker)會抱怨說這些函式是有宣告,但是還有實作起來。這些訊息可能會很模糊,向GCC產生的錯誤訊息就像這樣:
finddialog.o: In function `FindDialog::tr(char const*, char const*)’:
/usr/lib/qt/src/corelib/global/qglobal.h:1430: undefined reference to
`FindDialog::staticMetaObject’
Visual C++的輸出則像是這樣:
finddialog.obj : error LNK2001: unresolved external symbol
“public:~virtual int __thiscall MyClass::qt_metacall(enum QMetaObject
::Call,int,void * *)”
如果這狀況曾經發生過在你身上,再執行一次qmake去更新makefile,就可以重新建構好應用程式。如果快捷鍵已經顯示在你的平台上的話,現在執行這個程式,判別這些快捷鍵 Alt+W、Alt+C、 Alt+B和 Alt+F 是否有正確的運作。
按下TAB鍵去轉換這個部件所有的欄位,預設的TAB順序是可以被建立,也可以用QWidget::setTabOrder()來改變。提供合理順序的快捷鍵可以確保不喜歡使用滑鼠的使用者能夠充分的使用的這個應用程式。完整的鍵盤控制也是能加速打字。
在第三章裡,我們將在真實的應用程式使用Find對話方塊,我們將會利用findPrevious()和findNext() 訊號(Signal)去連結一些訊息孔(Slot)。