QtResources/bg: Difference between revisions
No edit summary |
No edit summary |
||
Line 1: | Line 1: | ||
'''Български''' [[QtResources|English]] [[QtResources SimplifiedChinese|简体中文]]<br />[[Category:QtInternals]] | '''Български''' [[QtResources|English]] [[QtResources SimplifiedChinese|简体中文]]<br />[[Category:QtInternals]] | ||
[toc align_right= | [toc align_right="yes" depth="1"] | ||
Написано от : Girish Ramakrishnan, ForwardBias Technologies | Написано от : Girish Ramakrishnan, ForwardBias Technologies | ||
Line 7: | Line 7: | ||
= Общ преглед = | = Общ преглед = | ||
''Qt Resources'' предоставя платформено независим механизъм за вкарване на произволни бинарни данни, включително изображения и звуци, като част от изпълнимият файл на приложението. Вижте | ''Qt Resources'' предоставя платформено независим механизъм за вкарване на произволни бинарни данни, включително изображения и звуци, като част от изпълнимият файл на приложението. Вижте "документацията на ресурсите":http://doc.qt.nokia.com/snapshot/resources.html за по-подробна информация. | ||
По отношение на имплементацията, ресурсите в Qt нямат нищо общо с | По отношение на имплементацията, ресурсите в Qt нямат нищо общо с "RES файловете":http://msdn.microsoft.com/en-us/library/ms648007.aspx на Windows или "resource forks":http://en.wikipedia.org/wiki/Resource_fork on Mac OS X. | ||
= Как работи = | = Как работи = | ||
Ресурсните файлове (i.e .qrc files) са XML-и, които описват кои файлове трябва да се пакетират в крайният бинарен файл. Ресурсният компилатор ''rcc'' обхожда XML-а и генерира C/C++ код. Този генериран код съдържа C структура, която съдържа суровите данни на файловете, който се намират в .qrc. След това тези C-структури се събират в друга C-структура, за да формират дървовидна структура, така че файловете да могат да се наредят в йерархии. Детайлите за тази структура сами по себе си не са много интересни, за това и не са описани тук. С опцията | Ресурсните файлове (i.e .qrc files) са XML-и, които описват кои файлове трябва да се пакетират в крайният бинарен файл. Ресурсният компилатор ''rcc'' обхожда XML-а и генерира C/C++ код. Този генериран код съдържа C структура, която съдържа суровите данни на файловете, който се намират в .qrc. След това тези C-структури се събират в друга C-структура, за да формират дървовидна структура, така че файловете да могат да се наредят в йерархии. Детайлите за тази структура сами по себе си не са много интересни, за това и не са описани тук. С опцията -''compressed'' на rcc, данните в структурите се компресират със zlib (по подразбиране, компресирането е изключено). | ||
<br />C-структурите трябва да се регистрират в Qt, за да може то да знае за тях. Номера е, че в края на всеки генериран от rcc C++ файл, rcc слага извикване на qRegisterResourceData(), което регистрира C структурата в системата за ресурси на Qt. Чрез използването на ''подхода за конструктурна функция'', qRegisterResourceData() се извиква преди main(). ''Подхода за конструктурната функция'' е използването на глобална статична променлива, която се инициализира като се извиква функция.<br /><code><br />#ifndef Q_CONSTRUCTOR_FUNCTION<br /># define Q_CONSTRUCTOR_FUNCTION0(AFUNC) static const int AFUNC ## ''init_variable'' = AFUNC (); | <br />C-структурите трябва да се регистрират в Qt, за да може то да знае за тях. Номера е, че в края на всеки генериран от rcc C++ файл, rcc слага извикване на qRegisterResourceData(), което регистрира C структурата в системата за ресурси на Qt. Чрез използването на ''подхода за конструктурна функция'', qRegisterResourceData() се извиква преди main(). ''Подхода за конструктурната функция'' е използването на глобална статична променлива, която се инициализира като се извиква функция.<br /><code><br />#ifndef Q_CONSTRUCTOR_FUNCTION<br /># define Q_CONSTRUCTOR_FUNCTION0(AFUNC) static const int AFUNC ## ''init_variable'' = AFUNC (); | ||
# define Q_CONSTRUCTOR_FUNCTION(AFUNC) Q_CONSTRUCTOR_FUNCTION0(AFUNC)<br />#endif<br /></code> | # define Q_CONSTRUCTOR_FUNCTION(AFUNC) Q_CONSTRUCTOR_FUNCTION0(AFUNC)<br />#endif<br /></code> | ||
Line 20: | Line 20: | ||
<br />Тъй като статичните променливи се инициализират преди извикаването на main(), всички ресурси автоматично се регистрират преди същинската програма да стартира. | <br />Тъй като статичните променливи се инициализират преди извикаването на main(), всички ресурси автоматично се регистрират преди същинската програма да стартира. | ||
<br />h1. Q_INIT_RESOURCE | <br />h1. Q_INIT_RESOURCE | ||
<br />Трикът с конструкторната функция работи само ако генерирания C++ файл е компилиран и вързан за приложението директно. Ако ресурсите се използват в статична библиотека и тя е свързана с приложението, конструкторната функция никога няма да се извика. Това е в природата на C/C++ свръзването | <br />Трикът с конструкторната функция работи само ако генерирания C++ файл е компилиран и вързан за приложението директно. Ако ресурсите се използват в статична библиотека и тя е свързана с приложението, конструкторната функция никога няма да се извика. Това е в природата на C/C++ свръзването- функциите и променливите в библиотеките, които не се използват/извикват от крайната програма се премахват от крайният бинарен код ( оптимизират се). Ако ресурсите са в споделена библиотека, тогава конструкторната функция се извиква. Обаче, повечето платформи зареждат споделените библиотеки при нужда и конструктурната функция се извиква само когато библиотеката се зарежда. Последствието от това е, че всички ресурси в плъгини, които се използват в главната програма, няма да бъдат намерени от Qt, докато плъгина не бъде зареден - това не е проблем, ако ресурсиоте от споделената библиотека се изпозлват само в нея. Обърнете внимание на това, че достъпването на ресурси от споделената библиотека в главното приложение не предизвиква зареждането и, тъй като никакви символи не се експортират от QRC системата. | ||
Решението на този проблем е да се използва генерирана променлива( от AFUNC ## ''init_variable'' по-горе) или да се извика генерираната функция qInitResource_images(). Макросът Q_INIT_RESOURCE съществува с тази цел и се ''изисква, когато имате ресурси в статична или споделена библиотека''. | Решението на този проблем е да се използва генерирана променлива( от AFUNC ## ''init_variable'' по-горе) или да се извика генерираната функция qInitResource_images(). Макросът Q_INIT_RESOURCE съществува с тази цел и се ''изисква, когато имате ресурси в статична или споделена библиотека''. | ||
Line 30: | Line 30: | ||
= Достъпване на ресурси = | = Достъпване на ресурси = | ||
QFile, QDir, QPixmap и т.н. могат да достъпват qrc файлове. Целият достъп до файлове в Qt минава през | QFile, QDir, QPixmap и т.н. могат да достъпват qrc файлове. Целият достъп до файлове в Qt минава през "QAbstractFileEngine":http://doc.trolltech.com/4.6/qabstractfileengine.html. QResource регистрира подклас на QAbstractFileSystemEngine при стартиране, който предоставя валидна система за достъп до файлове (през QAbstractFileEngine::create), когато името на файла започва с ":". | ||
= Именни пространства за ресурси = | = Именни пространства за ресурси = | ||
Когато използвате ресурси в плъгини, ресурсните пътища трябва да бъдат именовани. Използването на името на плъгина за именоване на ресурсното пространство е добра техника. За пример, '':/plugin_name/resourcename''. Ако съществуващ път до ресурси е регистриран втори път с различни данни, той се игнорира и се запазва първия. | Когато използвате ресурси в плъгини, ресурсните пътища трябва да бъдат именовани. Използването на името на плъгина за именоване на ресурсното пространство е добра техника. За пример, '':/plugin_name/resourcename''. Ако съществуващ път до ресурси е регистриран втори път с различни данни, той се игнорира и се запазва първия. |
Revision as of 06:48, 25 February 2015
[toc align_right="yes" depth="1"]
Написано от : Girish Ramakrishnan, ForwardBias Technologies
Общ преглед
Qt Resources предоставя платформено независим механизъм за вкарване на произволни бинарни данни, включително изображения и звуци, като част от изпълнимият файл на приложението. Вижте "документацията на ресурсите":http://doc.qt.nokia.com/snapshot/resources.html за по-подробна информация.
По отношение на имплементацията, ресурсите в Qt нямат нищо общо с "RES файловете":http://msdn.microsoft.com/en-us/library/ms648007.aspx на Windows или "resource forks":http://en.wikipedia.org/wiki/Resource_fork on Mac OS X.
Как работи
Ресурсните файлове (i.e .qrc files) са XML-и, които описват кои файлове трябва да се пакетират в крайният бинарен файл. Ресурсният компилатор rcc обхожда XML-а и генерира C/C++ код. Този генериран код съдържа C структура, която съдържа суровите данни на файловете, който се намират в .qrc. След това тези C-структури се събират в друга C-структура, за да формират дървовидна структура, така че файловете да могат да се наредят в йерархии. Детайлите за тази структура сами по себе си не са много интересни, за това и не са описани тук. С опцията -compressed на rcc, данните в структурите се компресират със zlib (по подразбиране, компресирането е изключено).
C-структурите трябва да се регистрират в Qt, за да може то да знае за тях. Номера е, че в края на всеки генериран от rcc C++ файл, rcc слага извикване на qRegisterResourceData(), което регистрира C структурата в системата за ресурси на Qt. Чрез използването на подхода за конструктурна функция, qRegisterResourceData() се извиква преди main(). Подхода за конструктурната функция е използването на глобална статична променлива, която се инициализира като се извиква функция.
<br />#ifndef Q_CONSTRUCTOR_FUNCTION<br /># define Q_CONSTRUCTOR_FUNCTION0(AFUNC) static const int AFUNC ## ''init_variable'' = AFUNC ();
# define Q_CONSTRUCTOR_FUNCTION(AFUNC) Q_CONSTRUCTOR_FUNCTION0(AFUNC)<br />#endif<br />
В края на генерирания от rcc C++ файл, съдържа нещо подобно на:
<br />int qInitResources_images()<br />{<br /> qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data);<br /> return 1;<br />}
<br />Q_CONSTRUCTOR_FUNCTION(qInitResources_images)<br />
Тъй като статичните променливи се инициализират преди извикаването на main(), всички ресурси автоматично се регистрират преди същинската програма да стартира.
h1. Q_INIT_RESOURCE
Трикът с конструкторната функция работи само ако генерирания C++ файл е компилиран и вързан за приложението директно. Ако ресурсите се използват в статична библиотека и тя е свързана с приложението, конструкторната функция никога няма да се извика. Това е в природата на C/C++ свръзването- функциите и променливите в библиотеките, които не се използват/извикват от крайната програма се премахват от крайният бинарен код ( оптимизират се). Ако ресурсите са в споделена библиотека, тогава конструкторната функция се извиква. Обаче, повечето платформи зареждат споделените библиотеки при нужда и конструктурната функция се извиква само когато библиотеката се зарежда. Последствието от това е, че всички ресурси в плъгини, които се използват в главната програма, няма да бъдат намерени от Qt, докато плъгина не бъде зареден - това не е проблем, ако ресурсиоте от споделената библиотека се изпозлват само в нея. Обърнете внимание на това, че достъпването на ресурси от споделената библиотека в главното приложение не предизвиква зареждането и, тъй като никакви символи не се експортират от QRC системата.
Решението на този проблем е да се използва генерирана променлива( от AFUNC ## init_variable по-горе) или да се извика генерираната функция qInitResource_images(). Макросът Q_INIT_RESOURCE съществува с тази цел и се изисква, когато имате ресурси в статична или споделена библиотека.
<br />#define Q_INIT_RESOURCE_EXTERN(name) extern int qInitResources_ ## name();<br />
Макроса по-горе обикновено се слага в началото на main() за всеки qrc файл.
Достъпване на ресурси
QFile, QDir, QPixmap и т.н. могат да достъпват qrc файлове. Целият достъп до файлове в Qt минава през "QAbstractFileEngine":http://doc.trolltech.com/4.6/qabstractfileengine.html. QResource регистрира подклас на QAbstractFileSystemEngine при стартиране, който предоставя валидна система за достъп до файлове (през QAbstractFileEngine::create), когато името на файла започва с ":".
Именни пространства за ресурси
Когато използвате ресурси в плъгини, ресурсните пътища трябва да бъдат именовани. Използването на името на плъгина за именоване на ресурсното пространство е добра техника. За пример, :/plugin_name/resourcename. Ако съществуващ път до ресурси е регистриран втори път с различни данни, той се игнорира и се запазва първия.