目錄
一、認識 Qt SDK 的目錄結構
二、第一個 Qt 程序
2.1 Qt Creator 創建項目
2.2 介紹項目各文件
三、揭秘 Qt 的構建過程
四、運行項目與總結
?
?🎬 攻城獅7號:個人主頁
🔥 個人專欄:C++QT跨平臺界面編程
?? 君子慎獨!
?🌈 大家好,歡迎來訪我的博客!
?? 此篇文章主要介紹 Qt SDK 的目錄和第一個Qt Creator項目
📚 本期文章收錄在《C++QT跨平臺界面編程》,大家有興趣可以自行查看!
?? 歡迎各位 ?? 點贊 👍 收藏 ?留言 📝!
一、認識 Qt SDK 的目錄結構
????????在我們開始創建項目之前,先花點時間了解一下 Qt SDK 安裝后的目錄結構是很有幫助的。這能讓你明白編譯、鏈接和運行一個 Qt 程序時,那些必要的文件都來自哪里。
????????以一個典型的 Qt 安裝目錄為例(比如 `C:\Qt\Qt5.9.0`),你會看到幾個關鍵的子目錄:
????????進去5.9 目錄,會看到`msvc2015_64` / `mingw53_32` 等,這些是以 "編譯器_平臺" 命名的目錄,是你為特定平臺開發時真正用到的核心。其中Src是QT源碼目錄。
????????每個這樣的目錄里都包含:
(1)`bin`: 存放著可執行文件和動態鏈接庫(DLL)。這里面不僅有你程序運行時依賴的 `Qt5Core.dll`、`Qt5Gui.dll` 等,還有 Qt 開發工具鏈三劍客:`qmake.exe`(處理.pro文件生成Makefile)、`moc.exe`(元對象編譯器)和 `uic.exe`(UI編譯器)。Qt Designer (`designer.exe`) 和 Qt Assistant (`assistant.exe`,用于查閱官方文檔) 也在這里。
????????Qt Designer的功能:可視化 UI 設計工具,通過拖拽組件(按鈕、文本框等)快速創建界面,生成.ui
文件。
????????Qt Assistant的功能:集成式文檔瀏覽器,提供 Qt 框架的官方文檔、示例代碼和 API 參考。
(2) `include`: 存放所有 Qt 模塊的頭文件(`.h`)。你在代碼中 `#include <QWidget>` 時,編譯器就是在這里找到對應的文件。
(3) `lib`: 存放庫文件(`.lib`)。鏈接器在生成最終可執行文件時,需要這些文件來解析 Qt 的函數調用。
????????簡單來說,你在 Qt Creator 中選擇一個"Kit"(構建套件,例如 `Desktop Qt 5.9.0 MSVC2015 64bit`),實際上就是指定了使用哪個編譯器目錄下的 `bin`, `include`, `lib` 來編譯和鏈接你的項目。
????????下面是其他幾個主要的5.9 的同級目錄:
(1)`plugins`: 存放各類插件。比如,讓你的程序能顯示 JPG、GIF 圖片的圖像格式插件,或者連接 MySQL、SQLite 數據庫的驅動插件。發布程序時,往往需要把用到的插件(通常是整個目錄)一并打包。
(2)`Tools`: 包含了一些工具,比如 Qt Creator IDE 本身,以及可能的第三方編譯器套件(如 MinGW)。
(3)`Examples`: 包含了大量的官方示例項目源碼,是學習 Qt 非常好的參考資料。
(4)`Docs`: 存放著 Qt 的所有離線幫助文檔。
二、第一個 Qt 程序
2.1 Qt Creator 創建項目
????????現在我們用 Qt Creator 創建一個最基礎的 Qt Widgets 應用,首先是打開通過C:\Qt\Qt5.9.0\Tools\QtCreator\bin\qtcreator.exe 雙擊打開Qt Creator,或者在快速啟動欄點擊打開。按如下新建項目:
????????如下選擇項目類型:
????????如下填入項目名稱和路徑,路徑最好是英文。 然后下一步
????????如下只選擇一個編譯環境?
????????下一步自定義各文件,文件名稱最好都是小寫,避免代碼遷移到linux平臺,區分大小的不小心容易出錯
?如下便創建好了項目
????????其中widget.ui文件可以雙擊打開,如下拖放一個按鈕控件上去,點擊編輯模式,可以看到其ui代碼
如下是上面的項目testqt源碼文件:
2.2 介紹項目各文件
(1) `.pro` - 項目配置文件
????????這是一個項目(Project)文件,由 qmake 工具處理。它告訴 Qt 要如何編譯你的項目。
QT += core guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = testqtTEMPLATE = appSOURCES += main.cpp widget.cppHEADERS += widget.hFORMS += widget.ui
?
* ? `QT += core gui widgets`:聲明項目需要用到 Qt 的核心、GUI 和窗口部件模塊。qmake會據此去`lib`目錄和`include`目錄引用對應的庫和頭文件。
* ? `TARGET = testqt`:指定生成的可執行程序的名字。
* ? `TEMPLATE = app`:指定這是一個應用程序(app)項目。
* ? `SOURCES`、`HEADERS`、`FORMS`:分別列出了項目包含的源文件、頭文件和界面文件。qmake會根據這些清單來決定哪些文件需要被編譯,哪些需要被`moc`或`uic`處理。
(2)`.pro.user` - 用戶配置文件(重要概念)
????????在你的項目目錄下,還會看到一個 `testqt.pro.user` 文件。這個文件非常重要,但它不應該被包含在版本控制中(如 Git)。
????????它存儲的是你本地開發環境的配置,比如你選擇了哪個 Qt 版本和編譯器(即哪個 Kit),以及你的項目構建目錄在哪里等等。當你把項目發給別人時,應該刪掉這個文件。對方用他的 Qt Creator 打開 `.pro` 文件時,會自動生成一份適合他自己環境的 `.pro.user` 文件。
(3) `main.cpp` - 程序入口
????????和所有 C++ 程序一樣,`main` 函數是程序的起點。
#include "widget.h"
#include <QApplication>int main(int argc, char *argv[]){// 1. 創建 QApplication 實例,它是 Qt 程序的管理者QApplication a(argc, argv);// 2. 創建我們自己的窗口類 Widget 的實例Widget w;// 3. 顯示窗口w.show();// 4. 進入事件循環,等待用戶操作 (如點擊鼠標、按下鍵盤)return a.exec();}
? ? ? ??這個文件很固定,對于大部分應用來說,你幾乎不需要修改它。
(4) `widget.h` & `widget.cpp` - 窗口的定義與實現
????????這兩個文件定義了我們主窗口的行為。
`widget.h` (頭文件 - 聲明)
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>namespace Ui {
class Widget;
}class Widget : public QWidget
{Q_OBJECT // 重點:Qt 的"魔法"宏,使用信號與槽必須包含它public:explicit Widget(QWidget *parent = 0);~Widget();private:Ui::Widget *ui; // 重點:指向界面設計的指針
};#endif // WIDGET_H
* ? `class Widget : public QWidget`:我們的窗口類 `Widget` 繼承自 Qt 的基礎窗口部件 `QWidget`。
* ? `Q_OBJECT`:一個特殊的宏。只要你想在類中使用 Qt 強大的"信號與槽"機制,就必須加上它。`moc`工具會專門處理它。
* ? `Ui::Widget *ui;`:這是一個關鍵的指針。它指向由 `widget.ui` 文件生成的那個界面。通過 `ui` 指針,我們就可以在 C++ 代碼中訪問界面上的所有元素(比如按鈕、輸入框等)。
`widget.cpp` (源文件 - 實現)
#include "widget.h"
#include "ui_widget.h" // 重點:包含了 .ui 文件編譯后生成的頭文件Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{// 這行代碼將 .ui 文件中設計的界面和當前的 C++ 代碼"關聯"起來ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}
?
* ? `ui->setupUi(this);` 是最重要的部分。它會讀取 `.ui` 文件內容,并將其中設計的按鈕等控件實例化,把它們"畫"在 `Widget` 這個窗口上。
(5) `widget.ui` - 界面設計文件
????????這是一個 XML 文件,用 Qt Creator 的設計模式打開時,你可以通過拖拽的方式來設計界面。
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"><class>Widget</class><widget class="QWidget" name="Widget"><property name="geometry"><rect><x>0</x><y>0</y><width>671</width><height>478</height></rect></property><property name="windowTitle"><string>Widget</string></property><widget class="QPushButton" name="pushButton"><property name="geometry"><rect><x>230</x><y>170</y><width>191</width><height>101</height></rect></property><property name="text"><string>PushButton</string></property></widget></widget><layoutdefault spacing="6" margin="11"/><resources/><connections/>
</ui>
????????可以看到,我們在界面上放了一個 `QPushButton`,它的 `name` 是 `pushButton`,顯示的文本是 `PushButton`。在 C++ 代碼中,我們就可以通過 `ui->pushButton` 來訪問這個按鈕。
三、揭秘 Qt 的構建過程
????????當你點擊"運行"按鈕時,Qt Creator 在背后為你做了幾件重要的事情,最終才生成了可執行文件。這個過程通常發生在一個單獨的構建目錄中(比如 `build-testqt-Desktop_Qt_5_9_0...`)。
(1)`qmake` 生成 Makefile:`qmake.exe` 首先讀取你的 `testqt.pro` 文件。根據里面的配置,它會生成一個 `Makefile`(以及 `Makefile.Debug` 和 `Makefile.Release`)。Makefile 是一個構建規則文件,它精確定義了接下來需要執行的所有編譯和鏈接命令。
(2)`uic` (User Interface Compiler) 編譯 UI 文件:在編譯過程中,`uic.exe` 會被調用。它讀取 `widget.ui` 這個 XML 文件,并把它轉換成一個標準的 C++ 頭文件,名為 `ui_widget.h`。這個頭文件里定義了 `Ui::Widget` 類,并包含了創建所有界面控件(如 `pushButton`)的代碼。這個文件也被生成在構建目錄中。
(3)`moc` (Meta-Object Compiler) 處理元對象:接下來,`moc.exe` 會掃描你所有聲明了 `Q_OBJECT` 的頭文件(這里是 `widget.h`)。它會為這個類生成一些額外的 C++ 代碼(保存在 `moc_widget.cpp` 中),用于實現信號與槽等高級功能。
(4)C++ 編譯器編譯所有源文件:最后,你的 C++ 編譯器(如 MSVC 或 MinGW)會編譯所有的 `.cpp` 文件,這包括:
? ? * ? 你自己寫的 `main.cpp` 和 `widget.cpp`。
? ? * ? 由 `moc` 生成的 `moc_widget.cpp`。
(5)鏈接器生成可執行文件:編譯器將所有源文件編譯成目標文件(`.obj`)后,鏈接器會把這些目標文件與 Qt 庫(`.lib` 文件)鏈接起來,最終生成 `testqt.exe` 這個可執行文件。
????????了解這個過程有助于你排查一些奇怪的編譯錯誤。比如,如果你修改了 UI 文件但表現不正確,可能是 `uic` 沒有重新運行;如果信號槽不工作,有時是 `moc` 過程出了問題。這時,執行一次"清理項目"再"重新構建"通常能解決問題。
四、運行項目與總結
????????現在,重新編譯并運行程序。軟件左下角按順序的按鈕分別是,運行,編譯,構建
下面是它們的使用場景
?運行和構建的區別如下:
下面是程序運行的截圖:?
?
總結
????????通過這個簡單的例子,我們了解了:
????????(1)Qt SDK 的目錄結構,以及 `bin`、`lib`、`include` 的作用。
????????(2)一個 Qt 項目由 `.pro`、`.h`、`.cpp`、`.ui` 等文件組成,以及重要的 `.pro.user` 文件。
????????(3)Qt 通過 `qmake`、`uic` 和 `moc` 等工具將項目文件轉換、編譯并鏈接成可執行程序。
????????這只是 Qt 世界的冰山一角。接下來,你可以嘗試在界面上添加更多的控件(如 `QLabel`, `QLineEdit`),并用信號與槽將它們的功能連接起來,繼續你的探索之旅。關于信號和槽的概念學習我們后續章節見。
看到這里了還不給博主點一個:
?? 點贊
??收藏
?? 關注
!
💛 💙 💜 ?? 💚💓 💗 💕 💞 💘 💖
再次感謝大家的支持!
你們的點贊就是博主更新最大的動力!