Qt之資源系統

簡述

Qt 的資源系統用於存儲應用程序的可執行二進制文件,它採用平臺無關的機制。當你的程序總須要這樣的一系列文件(圖標、翻譯文件等)而且不想冒丟失某些文件的風險時,這就顯得十分有用。數組

資源系統基於 qmake、rcc(Qt 資源編譯器) 和 QFile 之間的緊密合做。markdown

資源集合文件(.qrc)

與程序相關的資源在被指定在一個 .qrc 文件中,其基於 XML 的文件格式列出了磁盤上的文件,能夠爲它們指定一個應用程序訪問資源時必須使用的資源名稱。app

下面是一個 .qrc 文件的示例:函數

<!DOCTYPE RCC><RCC version="1.0">
<qresource>
    <file>images/copy.png</file>
    <file>images/cut.png</file>
    <file>images/new.png</file>
    <file>images/open.png</file>
    <file>images/paste.png</file>
    <file>images/save.png</file>
</qresource>
</RCC>

.qrc 文件中列出的資源文件是程序代碼樹中的一部分。指定的路徑相對於 .qrc 文件所在目錄。注意:列出的資源文件必須位於 .qrc 文件所在目錄或其子目錄。ui

資源數據能夠編譯成二進制,進而在程序代碼中當即訪問;或者建立一個二進制資源,在晚些時候用資源系統來註冊程序代碼。this

默認狀況下,程序可使用與代碼樹中相同的名字訪問資源,須要帶有 「:/」 前綴,或者有qrc scheme的URL。spa

例如: :/images/cut.png 或者URL qrc:///images/cut.png 均可以訪問在程序代碼樹中位置爲 images/cut.png 的 cut.png 文件。用文件標籤的別名屬性能夠改變訪問名稱:操作系統

<file alias="cut-img.png">images/cut.png</file>

以後,在程序中就可使用 :/cut-img.png 訪問此文件了。還可使用 qresource 標籤的前綴屬性爲 .qrc 文件中列出的全部文件指定路徑前綴:插件

<qresource prefix="/myresources">
    <file alias="cut-img.png">images/cut.png</file>
</qresource>

這種狀況下,就可使用 :/myresources/cut-img.png 訪問該文件了。命令行

有些資源可能須要隨着用戶本地的配置而改變,例如:翻譯文件、圖標,能夠經過爲 qresource 標籤添加一個 lang 屬性,並指定一個適當的本地字符串來完成。例如:

<qresource>
    <file>cut.jpg</file>
</qresource>
<qresource lang="fr">
    <file alias="cut.jpg">cut_fr.jpg</file>
</qresource>

若是用戶的語言是法語(即:QLocale::system().name() 返回「fr_FR」),:/cut.jpg 就變成了對 cut_fr.jpg 文件的引用。若是是其它語言,仍然使用 cut.jpg 。

使用語言字符串的格式的說明能夠參考 QLocale 文檔。

外部二進制資源

要建立外部二進制資源,必須經過傳遞 -binary 給 rcc 來建立資源數據(一般使用 .rcc 擴展名),一旦二進制資源被建立,就可使用 QResource API 註冊該資源。

例如, .qrc 文件中指定的一系列資源數據能夠用下面的方式編譯:

rcc -binary myresource.qrc -o myresource.rcc

在程序裏,須要用如下代碼註冊該資源:

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

內編譯資源

要把一個資源編譯到二進制文件中, 必須在 .pro 中明確指定.qrc 文件,以便於 qmake 能夠正確處理。例如:

RESOURCES = application.qrc

qmake 會產生 make 規則來生成一個連接到程序中的名爲 qrc_application.cpp 的文件。這個文件以靜態的 C++ 壓縮二進制數組包含了全部圖片和其它資源的數據。當 qrc_application.cpp 自己或者是其引用的資源文件發生改變後,該文件都會被自動從新生成。若是你不使用 .pro 文件,那麼能夠手工調用 rcc 或者爲 build 系統添加 build 規則。

這裏寫圖片描述

目前,Qt 老是把資源數據存儲在可執行文件中,甚至是在 Windows、Mac OS X 和 iOS 這些原生支持資源機制的操做系統中。在未來的 Qt release 版本中可能會改變。

壓縮

默認狀況下,資源是被壓縮的(ZIP 格式),也能夠關閉壓縮。若是你的資源已經包含了一個壓縮格式(例如: .png 文件),這可能會比較有用。能夠經過命令行傳遞 -no-compress 來指定:

rcc -no-compress myresources.qrc

rcc 也在壓縮上給你提供了一些控制,當壓縮文件時,能夠指定壓縮級別和閾值水平時,例如:

rcc -compress 2 -threshold 3 myresources.qrc

在程序中使用資源

在程序中,資源路徑在大多數狀況能夠代替通常的文件系統路徑。特別是,能夠用資源路徑取代文件名傳遞給 QIcon、 QImage ,或者 QPixmap 的構造函數:

cutAct = new QAction(QIcon(":/images/cut.png"), tr("Cu&t"), this);

能夠參考 Application 示例,瞭解更多關於應用程序使用 Qt 資源系統來存儲圖標的內容。

在內存中,資源由一個資源對象樹來表示。此樹在程序啓動時被自動生成,並被 QFile 用來解析路徑到資源。你可使用帶有 「:/」 前綴的 QDir 從根目錄開始遍歷這棵樹。

Qt 資源系統支持搜索路徑列表。若是你用 : 代替 :/ 做爲前綴,則會使用搜索路徑列表來搜索資源。程序啓動時搜索路徑列表爲空,能夠用 QDir::addSearchPath() 爲其添加路徑。

若是有資源位於靜態庫中,須要用不帶有後綴的 .qrc 文件名爲參數調用 Q_INIT_RESOURCE() 來強制初始化資源系統。例如:

在庫中使用資源

若是有資源位於一個庫中,須要用不帶有後綴的 .qrc 文件名爲參數調用 Q_INIT_RESOURCE() 來強制初始化資源系統。例如:

MyClass::MyClass() : BaseClass()
{
    Q_INIT_RESOURCE(resources);

    QFile file(":/myfile.dat");
    ...
}

在靜態連接的狀況下,這確保了資源被連接到最終應用程序的二進制文件中。應該把初始化代碼接近庫中資源被使用的地方,這樣以來,若是庫的客戶端用庫的特性,它們只會連接進資源。

注意:因爲 rcc 初始化資源生成在全局命名空間中聲明,你也須要在任何命名空間以外的地方調用 Q_INIT_RESOURCE()。

若是庫內部包含未使用的資源,可是暴漏給庫的客戶端,初始化須要發生在應用程序代碼中,例如:

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    Q_INIT_RESOURCE(graphlib);

    QFile file(":/graph.png");
    ...
    return app.exec();
}

和以前同樣,這確保在靜態連接的狀況下,資源被連接到最終應用程序的二進制文件中,也觸發加載動態鏈,例如:插件。

一樣的,你必須明確地卸載一個顯式設置的資源(由於一個插件被卸載或資源再也不有效),你能夠強制刪除資源經過調用 Q_CLEANUP_RESOURCE() 與上面相同的基本名稱。

注意:當資源被構建爲應用程序的一部分時,沒有必要使用 Q_INIT_RESOURCE() 和Q_CLEANUP_RESOURCE()。

相關文章
相關標籤/搜索