應用需求:
提供皮膚切換選項,在不重新開機應用程式的情況下實作皮膚的動态切換。
理論基礎:
1) 圖檔資源是如何被利用的
這裡先簡要說明一下實作原理,皮膚的動态切換其關鍵在于圖檔資源的加載方式。qt中每個應用程式啟動後都會維護屬于自己的資源子庫,所有的圖檔以及ui資源都實作編譯到rcc檔案中,而rcc檔案是整合了所有資源的二進制檔案,這種方式屬于動态加載。
圖檔是一種資源,在qt中,對于資源的使用有以下幾點:
1> 一般來說:資源在記憶體中是用資源對象樹來表示的,該樹在程式啟動時建立。
2> 對于資源而言:都是需要先将其加入到這棵樹中才能加載到記憶體中并被程式使用。
3> 将一個圖檔資源動态加載到資源的對象樹中是用函數:qresource::registerresource()來實作的,即先将資源向這顆資源對象樹進行注冊,這樣才可以在程式中使用該資源葉子。資源一旦注冊到資源子樹中它就會占用記憶體。
4> 當不再需要使用某個資源圖檔時,我們不希望它繼續占用記憶體,此時需要用qresource::unregisterresource()來進行反注冊。此函數的作用就是在資源對象樹中周遊找到代表該資源的節點,然後delete釋放它。
總的來說就是:一個程式所用到的資源都是放到一棵資源對象樹中的,當程式啟動時該樹便會自動建立,而當我們使用某個資源時都需要實作将其向該樹進行注冊,當不需要時則需要進行反注冊。
2) 圖檔資源使用的三種方式
1> 在程式運作時加載圖檔
這是最簡單的一種使用方法,例如:image = newqimage(“1.png”),這種方法在程式運作時再去加載圖檔,需要在對應目錄下事先放置好圖檔,這樣做的優點是程式 運作時不需要的檔案不會加載,節省了記憶體,但是這種方式是i/o讀取,是以速度會相對慢一些。
2> 将圖檔編譯進工程
這種方式是在pro檔案下添加一行:resources = test.qrc ; qrc檔案中添加了對圖檔資源的引用,它的格式如下:
這樣程式在釋出時不需要在目錄下放置圖檔,利用該qrc檔案在編譯的時候會自動生成qrc_test.cpp檔案,裡面主要是利用三個數組來存放圖檔的二進制資料。
當使用qrc資源檔案時,系統會自動将所有的圖檔資源都向程式的資源對象樹進行注冊,并且當程式結束時再進行反注冊。使用這種方式,由于圖檔資源一直在記憶體中,避免了i/o操作,加快了讀取速度,但是卻是以消耗記憶體為代價的。
3> 手動進行注冊
上面利用qrc檔案是程式運作時一次性将圖檔資源全部加載到資源對象樹中,直到程式運作結束才會反注冊。而最佳的實作方式是:需要用到時,将資源加載進來,不需要的時候可以對資源進行反注冊,進而可以節省記憶體。
這種方法的主要步驟為:
1) 利用qrc和qss檔案生成rcc二進制資源檔案:rcc.exe –binary test.qrc –o test.rcc
2) 在需要的時候将該資源向程式的資源對象樹進行注冊使用。
3) 在不需要時進行反注冊。
皮膚插件系統的實作:
皮膚插件系統實作的基本邏輯圖如下:
其實作原理就是根據上面的三種方式,手動進行rcc檔案的注冊與反注冊。這裡需要強調的一點是:每個子產品都有自己的一套:qrc、qss以及他們生成的rcc檔案,因為我們利用rcc檔案就是避免它一次性将所有的資源注冊上(如果每套皮膚隻用一個rcc檔案将所有的資源都注冊上,在記憶體方面沒有優勢,隻是提供了可以進行皮膚動态切換的可能,gf2中的每套皮膚就隻有一個rcc檔案),需要時注冊,不需要時反注冊,是以我們需要手動地控制哪個子產品合适注冊、何時反注冊。比如:程式啟動先注冊login子產品的資源檔案,當登入成功後,登入界面就消失了,然後主面闆開始出現,這個時候我們就可以将登入子產品注冊的資源檔案進行反注冊。如果主界面邏輯中還有一個按鈕是顯示所有檔案同步資訊的,當我們點選時,檔案資訊子產品注冊上,關閉視窗時,檔案資訊子產品資源反注冊,而此時主面闆子產品資源一直都是注冊着的。采用這種方式,可能會花費一些精力還處理不同子產品資源的注冊與反注冊。
總結:
這裡的關鍵還是要了解動态方式使用rcc檔案,它是插件系統得以實作的基礎,本質就是向資源對象樹中的注冊與反注冊。注意:這裡充分利用了配置檔案的優點,還是基于插件的體系。由于界面具體的樣式還沒有細調,這裡就不上圖了,不過已經可以實作皮膚的動态切換了。聯想到其它,所有皮膚切換的實作原理都基本相似吧,自己的知識盲區中又少了一塊,加油!!五一來臨。