《第一個Qt程式》中使用 MainWindow 作為主介面,內建一個 QLabel 控制元件,所有程式碼都寫在 main() 函數內部。本節我們將主要程式碼封裝到一個類的內部,然後在 main() 函數中建立該類的物件,這貌似更加符合 C++ 規範。
編寫程式碼
我們在 D:QtDemo 資料夾建立三個程式碼檔案,分別是 MyMainWindow.h、MyMainWindow.cpp 和 main.cpp,各個檔案的具體程式碼如下所示。
1) MyMainWindow.h 檔案程式碼:
#ifndef MYMAINWINDOW_H
#define MYMAINWINDOW_H
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QLabel>
class MyMainWindow : public QMainWindow
{
Q_OBJECT
public:
MyMainWindow();
~MyMainWindow();
private:
QLabel *m_pLabel;
};
#endif
MYMAINWINDOW_H 可以防止標頭檔案被重複包含,不了解的讀者請猛擊《防止C語言標頭檔案被重複包含》。
Q_OBJECT 是一個宏,這種寫法對初學者來說是非常陌生的,它是 Qt 自己的語法擴充套件。Qt 的這種做法像極了早期的 C++:
-
C++ 在C語言的基礎上發展而來,C++ 擴充套件了C語言的語法,早期的 C++ 程式碼都是先被轉換為C語言程式碼,再使用C語言編譯器編譯。
-
Qt 是基於 C++ 的,但是它對 C++ 的語法進行了擴充套件(比如信號和槽機制、內省機制等),並增加了一些關鍵字(例如 signals、slots、emit 等),在真正編譯之前,擴充套件語法先被轉換成 C++ 程式碼(通過 moc 工具),然後再使用 C++ 編譯器編譯。
Qt 想要的功能 C++ 沒有,怎麼辦?那就自己上,親自實現這個功能!為了支援這些擴充套件功能,Qt 甚至實現了一個微型編譯器——元物件編譯器(Meta-Object Compiler, moc)。
C++ 為了保持程式執行的高效性,僅通過 RTTI(Run-Time Type Information,執行時型別識別)提供了非常簡陋的內省機制,幾乎沒有用武之地。Qt 拋棄了 C++ 自帶的內省機制,另起爐灶,創造了更加強大的元物件(meta object)系統,以此來支援完整的內省機制。
Q_OBJECT 宏就宣告了 Qt 元物件系統必須的函數和成員變數,之後我們會用 moc 工具生成元物件系統的實體函數程式碼。繼承 Qt 類時建議在類宣告的開頭新增 Q_OBJECT 宏,否則有時會出現莫名其妙的錯誤;如果你使用了信號和槽機制,Q_OBJECT 宏就是必須新增的,因為信號和槽依賴於元物件系統。
2) MyMainWindow.cpp 檔案程式碼:
#include "MyMainWindow.h"
MyMainWindow::MyMainWindow(): QMainWindow(){
this -> setWindowTitle("MyMainWindow演示"); //設定標題
this -> resize(360, 140); //設定客戶區大小
m_pLabel = new QLabel("C語言中文網", this);
m_pLabel -> setGeometry(130, 50, 160, 30); //設定Label控制元件的幾何尺寸
}
MyMainWindow::~MyMainWindow(){
delete m_pLabel;
m_pLabel = NULL;
}
該原始檔裡只有一個建構函式和一個解構函式。注意解構函式,它刪除之前 new 的標籤控制元件物件,並把指標設定為 NULL。
3) main.cpp 檔案程式碼:
#include <QtWidgets/QApplication>
#include "MyMainWindow.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyMainWindow w;
w.show();
return app.exec();
}
main 函數還是一如既往的簡單,由於使用自定義的 MyMainWindow 作為主視窗類,所以是包含了 MyMainWindow.h 和 QApplication 兩個標頭檔案。
編譯程式碼
需要手工編寫的程式碼就這些,接下來的任務就是如何編譯生成可執行程式了。
前面提到 Qt 元物件系統,Qt 是基於 C++ 開發的,而 C++ 本身並沒有元物件系統。元物件系統是 Qt 專門為 C++ 做的擴充套件功能,用於支援非常強大的信號/槽機制、內省機制等,後面我們會詳細講解,本節我們重點學習 moc 工具的使用。下面逐步介紹編譯連結本節程式的過程。
1) 進入資料夾
開啟 Qt 命令列工具,進入程式碼所在資料夾:
cd /d D:QtDemo
2) 使用 moc 工具
使用 moc 工具生成 MyMainWindow 類的元物件系統程式碼檔案 moc_MyMainWindow.cpp :
moc MyMainWindow.h -o moc_MyMainWindow.cpp
moc 工具會搜尋標頭檔案 MyMainWindow.h 裡面所有的 Q_OBJECT 宏,並生成相應的元物件系統實際原始碼,輸出儲存為 moc_MyMainWindow.cpp 檔案。
3) 編譯和連結 .cpp 檔案
加上剛才手動編寫的 MyMainWindow.cpp 和 main.cpp,我們總共要編譯三個 C++ 原始碼檔案:
g++ moc_MyMainWindow.cpp MyMainWindow.cpp main.cpp -std=c++0x -I"D:Qt5.9mingw53_32include" -L"D:Qt5.9mingw53_32lib" -lQt5Core -lQt5Gui -lQt5Widgets -o main
4) 執行 main.exe
生成 main.exe 之後,在 Qt 命令列工具裡輸入
main.exe
命令就可以執行該程式,看到顯示的效果。
生成 main.exe 的整個流程