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 的简短名字形式,不需要扩展名。

  • 6
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值