Qt下moc, uic, rcc命令的詳細使用說明

描述

qt是一個c++的界面庫,其特點就是其源碼可以跨平臺編譯,這樣在寫自己的小工具時可以方便地在windows,mac或linux環境下移植了。在windows下寫c++程序當然選vs,在mac下寫程序當然用xcode,在linux下就完全控制檯

使用

MOC

Qt將源代碼交給標準C++編譯器,如gcc之前,需要事先將這些擴展的語法去除掉。完成這一操作的就是moc。
moc全稱是Meta-Object Compiler,也就是“元對象編譯器”。Qt程序在交由標準編譯器編譯之前,先要使用moc分析C++源文件。如果它發現在一個頭文件中包含了宏 Q_OBJECT,則會生成另外一個 C++ 源文件。這個源文件中包含了Q_OBJECT宏的實現代碼。這個新的文件名字將會是原文件名前面加上 moc_ 構成。這個新的文件同樣將進入編譯系統,最終被鏈接到二進制代碼中去。因此我們可以知道,這個新的文件不是“替換”掉舊的文件,而是與原文件一起參與編譯。另外,我們還可以看出一點,moc 的執行是在預處理器之前。因爲預處理器執行之後,Q_OBJECT宏就不存在了。
總結:
1.moc 就是“元對象編譯器”;
2.Qt程序在交給標準編譯器預編譯之前要使用 moc 分析 C++ 源文件;
3.如果有宏 Q_OBJECT,則生成一個包含Q_OBJECT 宏的實現代碼的C++源文件;
4.新生成的源文件參與到標準編譯器的編譯中;
5.編譯過程中如果找不到對應的moc文件就會出現鏈接錯誤,此時要添加上對應的moc文件;
命令行輸入:

moc yourfilename.h -o moc_youfilename.cpp

生成不帶Q_OBJENT的源文件。
運行報錯:No relevant classes found. No output generated
解決:需要繼承於QObject類以及包含宏 Q_OBJECT,如下:
在這裏插入圖片描述

UIC

用designer設計的*.ui文件可以通過uic工具轉換爲*.h文件(在編譯時也會自動生成這樣一個ui_.h文件),有了這個.h文件就可以直接按照純C++的方式對其中的類進行調用。ui文件的使用就是利用默認工具uic自動產生一個類,然後用該類的setui函數加載界面到相應的對象上。
.ui文件的使用有三種形式:第一種是直接使用,第二種是定義一個新類,聲明一個ui子對象,利用該對象來加載界面,第三種是將ui作爲基類派生新的類。
雖然不使用designer來設計界面,但在編譯一個demo項目時都會用
.ui文件,這時得先將其用uic.exe進行轉化

uic.exe app.ui -o ui_app.h
uic.exe app.ui -o ui_app.cpp

其中app.ui是用designer設計好的界面文件,ui_app.h是生成的頭文件。然後在c++項目中#include "ui_app.h"即可。

RCC

RCC的命令參數可以通過在cmd下輸入相應的命令參看。如:
在這裏插入圖片描述
Qt 自帶的開發工具集裏有專門的 rcc 工具,用於將 .qrc 裏面描述的圖片、文檔等編譯成對應的源代碼文件 qrc_.cpp 或者獨立的二進制資源文件 *.rcc。
*(1)生成獨立的二進制資源文件 .rcc
對於太大的圖片、音頻、視頻等文件,不適合集成到目標程序內部,可以放到操作系統文件路徑,或者單獨編譯成外掛資源 *.rcc 。舉例來說,myresource.qrc 包含了很多圖片和視頻,沒法編譯成目標程序內嵌資源時,可以打開 Qt 命令行,進入 myresource.qrc 所在的文件夾,執行命令:

rcc -binary myresource.qrc -o myresource.rcc

rcc 會把 myresource.qrc 裏面描述的所有圖片、視頻等文件,都壓縮打包,生成一個二進制的 myresource.rcc 文件,這個 myresource.rcc 包含了所有的資源,這樣程序發佈時就不需要帶一堆亂七八糟的碎文件了,一個 myresource.rcc 搞定。
那麼代碼中如何使用 myresource.rcc 呢?需要在 main 函數開始的位置註冊這個獨立的二進制資源文件:

QResource::registerResource("/path/to/myresource.rcc");

然後也可使用之前類似的虛擬文件路徑,比如":/images/copy.png"、":/images/cat.gif" 。二進制資源文件 *.rcc 是用於外掛的,其實應用程序裏面更常見的是內嵌資源,接下來介紹內嵌使用方式。
在qml中使用rcc的內容,前綴是 **qrc:/** ;在 Qt 中使用, 前綴是 **:**

(2)應用程序內嵌資源
如果希望一個資源描述文件 application.qrc 在程序編譯時內嵌到目標程序裏,需要在*.pro 文件里加一句話:

RESOURCES += application.qrc

qmake 會自動根據這句話,爲 application.qrc 添加編譯腳本,編譯過程如下圖所示:
在這裏插入圖片描述
rcc工具會解析 application.qrc內的 XML文本,找到需要添加的各種文件,默認情況下,rcc 工具會對這些文件做ZIP壓縮,然後將壓縮後的ZIP數據的每個字節轉換成比如 0x6f數值形式,所有文件壓縮後的數據對應一個C++靜態數組 qt_resource_data[],並添加註冊、取消註冊、初始化、清除等函數和資源描述結構體,最終形成一個 qrc_application.cpp文件。然後用編譯器編譯qrc_application.cpp文件,得到 qrc_applicaotion.o ,鏈接到目標程序內部,就可以用 “:/images/copy.png” 等形式訪問程序內嵌資源了。
注意到剛纔向 .pro 文件裏添加 qrc 資源描述文件使用的運算符是+=,也就是說可以爲應用程序添加多個.qrc 文件,如果涉及的圖片比較多,可以用多個*.qrc 對圖片分類存放:

RESOURCES += buttons.qrc 
RESOURCES += backgrounds.qrc

使用多個*.qrc 與使用一個*.qrc 的方式是一樣的,虛擬文件路徑都類似 “:/buttons/ok.png” 、":/backgrounds/bgmain.png" 等,這裏的 ok.png 放在項目文件夾的 buttons 子文件夾裏,而 bgmain.png 是放在項目文件夾的 backgrounds 子文件夾裏,因此兩個文件的路徑是不同的。
qmake 爲內嵌資源添加的 rcc 編譯命令,類似下面這樣:

rcc -name application  application.qrc -o qrc_application.cpp

得到 qrc_application.cpp 源文件之後,剩下的編譯、鏈接就與普通 .cpp 文件一模一樣了。
qrc_application.cpp 文件中不僅有各種圖片、文檔對應的靜態數組,還有些結構體和函數,比如初始化和清除函數。
對於rcc命令,如果不加-name application選項參數,那麼在 qrc_application.cpp 裏面生成的初始化和清除函數名爲:

int QT_RCC_MANGLE_NAMESPACE(qInitResources)();
int QT_RCC_MANGLE_NAMESPACE(qCleanupResources)();

如果加了-name application選項參數,那麼資源的初始化和清除函數名變爲:

int QT_RCC_MANGLE_NAMESPACE(qInitResources_application)();
int QT_RCC_MANGLE_NAMESPACE(qCleanupResources_application)();

QT_RCC_MANGLE_NAMESPACE() 這個宏其實沒什麼用,僅用於提示作用。資源的初始化函數和清除函數會在資源加載和卸載時自動被調用。
應用程序的內嵌資源通常不需要手動初始化,但也有例外情況,比如在使用某些鏈接庫中的資源文件時,如果出現使用了正確的文件路徑 “:/images/copy.png” 卻找不到資源裏圖片文件的情況,那麼需要在使用該資源的類聲明裏或者在 main 函數裏打頭的位置加入一句手動初始化:

Q_INIT_RESOURCE(resources);

resources 是指 resources.qrc 的簡短名字形式,不需要擴展名。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章