全部博文(306)
分类: LINUX
2010-11-05 11:59:39
Qt
資源系統(Resource
System)可以提供與平台無關的機制,讓您把應用程式的圖檔、語系檔、資料等儲存於可執行檔之中,避免相關的資源檔案遺失的問題,Qt資源系統是基於
qmake、rcc(resource compiler),並搭配QFile來使用,您必須在產生的.pro檔之中,告知資源群集檔(Resource
Collection File)的位置與名稱。 Qt资源系统(Resource
System)可以提供与平台无关的机制,让您把应用程式的图档、语系档、资料等储存于可执行档之中,避免相关的资源档案遗失的问题,Qt资源系统是基于
qmake、rcc(resource compiler),并搭配QFile来使用,您必须在产生的.pro档之中,告知资源群集档(Resource
Collection File)的位置与名称。 資源群集檔的副檔名為.qrc,實際的內容為XML格式的檔案,當中告知了這個應用程式所要使用到的資源檔案,例如您想要將中所使用到的圖檔儲存在可執行檔案之中,則可以撰寫一個resourcefile.qrc: 资源群集档的副档名为.qrc,实际的内容为XML格式的档案,当中告知了这个应用程式所要使用到的资源档案,例如您想要将中所使用到的图档储存在可执行档案之中,则可以撰写一个resourcefile.qrc:
檔案的路徑是相對於.qrc檔案的位置。 档案的路径是相对于.qrc档案的位置。 接著您要在產生的.pro檔案中,增加一行,告知.qrc檔案的位置,例如: 接着您要在产生的.pro档案中,增加一行,告知.qrc档案的位置,例如: RESOURCES = resourcefile.qrc RESOURCES = resourcefile.qrc qmake會產生出製造qrc _ resourcefile.cpp的規則,之後使用rcc產生.cpp檔案,當中會將想要嵌入的相關檔案,壓縮並轉換為代表二進位資料的C++靜態無號字元陣列,如果您的.qrc檔案內容有變動,在編譯時.cpp檔案也會重新產生。 qmake会产生出制造qrc _ resourcefile.cpp的规则,之后使用rcc产生.cpp档案,当中会将想要嵌入的相关档案,压缩并转换为代表二进位资料的C++静态无号字元阵列,如果您的.qrc档案内容有变动,在编译时.cpp档案也会重新产生。 如果要使用嵌入的資源,則要在路徑的前端放置:/ ,例如: 如果要使用嵌入的资源,则要在路径的前端放置:/ ,例如: QListWidget *listWidget = new QListWidget; QListWidget *listWidget = new QListWidget; listWidget->insertItem(0, new QListWidgetItem( listWidget->insertItem(0, new QListWidgetItem( QIcon(":/images/caterpillar_head.jpg"), "caterpillar")); QIcon(":/images/caterpillar_head.jpg"), "caterpillar")); listWidget->insertItem(1, new QListWidgetItem( listWidget->insertItem(1, new QListWidgetItem( QIcon(" :/images/ momor_head.jpg"), "momor")); QIcon(" :/images/ momor_head.jpg"), "momor")); listWidget->insertItem(2, new QListWidgetItem( listWidget->insertItem(2, new QListWidgetItem( QIcon(" :/images/ bush_head.jpg"), "bush")); QIcon(" :/images/ bush_head.jpg"), "bush")); listWidget->insertItem(3, new QListWidgetItem( listWidget->insertItem(3, new QListWidgetItem( QIcon(" :/images/ bee_head.jpg"), "bee")); QIcon(" :/images/ bee_head.jpg"), "bee")); listWidget->insertItem(4, new QListWidgetItem( listWidget->insertItem(4, new QListWidgetItem( QIcon(" :/images/ cat_head.jpg"), "cat")); QIcon(" :/images/ cat_head.jpg"), "cat")); 您也可以為資源檔案的路徑設置別名(Alias),例如: 您也可以为资源档案的路径设置别名(Alias),例如: 之後在程式中指定路徑時,就可以直接使用別名,例如: 之后在程式中指定路径时,就可以直接使用别名,例如: listWidget->insertItem(0, new QListWidgetItem( listWidget->insertItem(0, new QListWidgetItem( QIcon(":/caterpillar_head.jpg"), "caterpillar")); QIcon(":/caterpillar_head.jpg"), "caterpillar")); 您也可以為別名設置前置(Prefix),例如: 您也可以为别名设置前置(Prefix),例如: 之後每個別名都會自動加上前置,使用時如下: 之后每个别名都会自动加上前置,使用时如下: listWidget->insertItem(0, new QListWidgetItem( listWidget->insertItem(0, new QListWidgetItem( QIcon(":/resources/caterpillar_head.jpg"), "caterpillar")); QIcon(":/resources/caterpillar_head.jpg"), "caterpillar")); 您也可以搭配語系來使用嵌入的資源檔,例如若這麼設定: 您也可以搭配语系来使用嵌入的资源档,例如若这么设定: 當路徑指定為:/caterpillar_head.jpg,如果使用者是使用zh_TW語系,則會自動對應使用caterpillar_head_zh_TW.jpg,此一方法也可以用來載入.qm檔案,以實現多國語系支援,可參考 與 。 当路径指定为:/caterpillar_head.jpg,如果使用者是使用zh_TW语系,则会自动对应使用caterpillar_head_zh_TW.jpg,此一方法也可以用来载入.qm档案,以实现多国语系支援,可参考 与 。 The rccResource Compiler (rcc)tool is used to embed resources into a Qt application during the build process. It works by generating a C++ source file containing data specified in a Qt resource (.qrc) file. The Meta-Object Compiler, moc, is the program that handles . The moc tool reads a C++ header file. If it finds one or more class declarations that contain the macro, it produces a C++ source file containing the meta-object code for those classes. Among other things, meta-object code is required for the signals and slots mechanism, the run-time type information, and the dynamic property system. The C++ source file generated by moc must be compiled and linked with the implementation of the class. Qt 不是使用的“标准的” C++ 语言,而是对其进行了一定程度的“扩展”。这里我们从Qt新增加的关键字就可以看出来:signals、slots 或者 emit。所以有人会觉得 Qt 的程序编译速度慢,这主要是因为在 Qt 将源代码交给标准 C++ 编译器,如 gcc 之前,需要事先将这些扩展的语法去除掉。完成这一操作的就是 moc。 moc 全称是 Meta-Object Compiler,也就是“元对象编译器”。Qt 程序在交由标准编译器编译之前,先要使用 moc 分析 C++ 源文件。如果它发现在一个头文件中包含了宏 Q_OBJECT,则会生成另外一个 C++ 源文件。这个源文件中包含了 Q_OBJECT 宏的实现代码。这个新的文件名字将会是原文件名前面加上 moc_ 构成。这个新的文件同样将进入编译系统,最终被链接到二进制代码中去。因此我们可以知道,这个新的文件不是“替换”掉旧的文件,而是与原文件一起参与编 译。另外,我们还可以看出一点,moc 的执行是在预处理器之前。因为预处理器执行之后,Q_OBJECT 宏就不存在了。 既然每个源文件都需要 moc 去处理,那么我们在什么时候调用了它呢?实际上,如果你使用 qmake 的话,这一步调用会在生成的 makefile 中展现出来。从本质上来说,qmake 不过是一个 makefile 生成器,因此,最终执行还是通过 make 完成的。 为了查看 moc 生成的文件,我们使用一个很简单的 cpp 来测试: test.cpp
这是一个空白的类,什么都没有实现。在经过编译之后,我们会在输出文件夹中找到 moc_test.cpp: moc_test.cpp
可以看到,moc_test.cpp 里面为 Test 类增加了很多函数。然而,我们并没有实际写出这些函数,它是怎么加入类的呢?别忘了,我们还有 Q_OBJECT 这个宏呢!在 qobjectdefs.h 里面,找到 Q_OBJECT 宏的定义:
这下了解了:正是对 Q_OBJECT 宏的展开,使我们的 Test 类拥有了这些多出来的属性和函数。注意,QT_TR_FUNCTIONS 这个宏也是在这里定义的。也就是说,如果你要使用 tr() 国际化,就必须使用 Q_OBJECT 宏,否则是没有 tr() 函数的。这期间最重要的就是 virtual const QMetaObject *metaObject() const; 函数。这个函数返回 QMetaObject 元对象类的实例,通过它,你就获得了 Qt 类的反射的能力:获取本对象的类型之类,而这一切,都不需要 C++ 编译器的 RTTI 支持。Qt 也提供了一个类似 C++ 的 dynamic_cast() 的函数 qobject_case(),而这一函数的实现也不需要 RTTI。另外,一个没有定义 Q_OBJECT 宏的类与它最接近的父类是同一类型的。也就是说,如果 A 继承了 QObject 并且定义了 Q_OBJECT,B 继承了 A 但没有定义 Q_OBJECT,C 继承了 B,则 C 的 QMetaObject::className() 函数将返回 A,而不是本身的名字。因此,为了避免这一问题,所有继承了 QObject 的类都应该定义 Q_OBJECT 宏,不管你是不是使用信号槽。 本文出自 “豆子空间” 博客,请务必保留此出处http://devbean.blog.51cto.com/448512/355100 |
chinaunix网友2010-11-05 14:42:11
很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com