Qt编译理解(Qt 对 C++ 的扩展主要是3个方面)
沉沉的黑夜都是白天的前奏。——郭小川
舍弃IDE或qmake、cmake等工具的束缚,通过几个例子, 一步步从标准 C++ 的编译过渡到 Qt 的编译。
Qt 对 C++ 的扩展主要是3个方面:
1)元对象系统,包含Q_OBJECT宏的文件(.h, .cpp等)需要 moc 预处理
2)资源系统,.qrc 文件 需要 rcc 进行预处理
3)界面系统,.ui 文件 需要 uic 进行预处理
这3者之中,元对象系统最复杂,也是 Qt 程序中重要的。 Qt5增加的qml也是一个亮点!
例子一:简单的控制台程序
#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
int main(int argc, char** argv)
{
//#QApplication这个类是继承QCoreApplication的,而QCoreApplication有继承QObject的,//而QObject就是QT中最基本
//#的基类,也就是QT的根基了. QCoreApplication class is used by non-GUI applications to provide their event loop.
// http://doc.qt.io/qt-5/qcoreapplication.html#details
QCoreApplication app(argc, argv);
qDebug()<<"hello qt!";
app.exec();
}
一个很简单的例子,没用到Qt扩展:(也就是说,这是一个普通的C++程序)。
我们都知道,编译一个C++的程序,无非是 编译预处理,编译、链接
编译预处理器:头文件路径 和 必要的宏
编译器:一些编译参数
链接器:一些链接参数 和 要链接的库
# use g++
简单一行命令,即可生成 main.exe (linux下,则生成可执行程序 main)
g++ main.cpp -DQT_CORE_LIB -Ie:\Qt\4.7.0\include -o main -Le:\Qt\4.7.0\lib -lQtCore4
单行命令,很简单:
-I 指定头文件路径
-L 指定库文件路径
-l 指定需要链接的库
-D 定义必要的宏(其实对这个小程序,这个宏也没必要用)
-o 指定生成的可执行文件名
# use cl
简单一行命令,即可生成 main.exe
cl main.cpp -ID:/Qt/4.7.0/include -DQT_CORE_LIB -Femain -link -LIBPATH:D:/Qt/4.7.0/lib QtCore4.lib
依然很简单
-I 头文件路径
-D 定义必要的宏
-Fe 指定可执行程序文件名
-link 后面是链接器参数
-LIBPATH 库文件路径
# 例子二:简单的GUI程序
这次稍微复杂一点,不是单一的控制台程序,而是一个简单的GUI程序 :
//main.cpp :
#include <QtGui/QApplication>
#include "widget.h"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
Widget w;
w.show();
return app.exec();
}
///////////////////
//widget.h file:
#include <QtGui/QWidget>
class Widget : public QWidget
{
public:
Widget(QWidget * parent=NULL);
};
//widget.cpp
#include "widget.h"
Widget::Widget(QWidget * parent)
:QWidget(parent)
{
}
同样,这个程序未使用Qt的扩展,直接用C++的编译器编译:g++
g++ main.cpp widget.cpp -DQT_CORE_LIB -DQT_GUI_LIB -Ie:\Qt\4.7.0-beta2\include -o main -Le:\Qt\4.7.0-beta2\lib -lQtCore4 -lQtGui4
因为我们使用了QtGui模块,所以和前面相比:
增加了 -DQT_GUI_LIB 和 -lQtGui4
多了一个文件 widget.cpp
例子三:引入moc
Qt 对 C++ 的扩展主要是3个方面:
元对象系统,包含Q_OBJECT宏的文件(.h, .cpp等)需要 moc 预处理
资源系统,.qrc 文件 需要 rcc 进行预处理
界面系统,.ui 文件 需要 uic 进行预处理
这3者之中,元对象系统最复杂,也是 Qt 程序中重要的。其他两个你都可以不要,唯独这个不要就有点不像话了(没它还叫Qt程序么?像我们前面写的,只不过是普通的C++程序)
修改前面的widget.h,加入Q_OBJECT宏:
#include <QtGui/QWidget>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget * parent=NULL);
};
如何编译这个程序呢?例子二中的命令不能使用了!
添加一个宏后,发生了什么?我们看看 编译器将加入Q_OBJECT宏展开 后是什么样子的:
#include <QtGui/QWidget>
class Widget : public QWidget
{
static const QMetaObject staticMetaObject;
virtual const QMetaObject *metaObject() const;
virtual void *qt_metacast(const char *);
virtual int qt_metacall(QMetaObject::Call, int, void **);
...
public:
Widget(QWidget * parent=NULL);
};
编译器在预处理时会将加入Q_OBJECT宏展开,展开后相当于定义了许多函数,一下子多出来这么多函数,而且还没有函数体。
如何生成函数体呢?这正是moc所做的:
moc widget.h -o moc_widget.cpp
这样一来,这些函数都在 moc_widget.cpp 被实现了,只要我们将该文件一块编译链接就行了。
对g++来说,在例子二的基础上,直接添加一个 moc_widget.cpp 文件,然后一切正常了:
g++ main.cpp widget.cpp moc_widget.cpp -DQT_CORE_LIB -DQT_GUI_LIB -Ie:\Qt\4.7.0-beta2\include -o main -Le:\Qt\4.7.0-beta2\lib -lQtCore4 -lQtGui4
例子四:rcc和uic
本节中不讲例子(因为 rcc 和 uic 概念比较简单)
如果我们用了资源,那么需要一个 xxx.qrc 文件,这个文件呢,C++ 编译器不认识,于是
rcc xxx.qrc -o qrc_xxx.cpp
如果我们用了designer设计的界面 .ui。C++ 编译器不认识这个文件,于是
uic xxx.ui -o ui_xxx.h
这样一来,我们得到是就全是 .h 和 .cpp 的文件了,剩下的工作,你知道的,交给 C++ 编译器就行了。
最后理解一下qt的编译工具:

Ref:
https://blog.csdn.net/luoqindong/article/details/53469909
Qt编译理解(Qt 对 C++ 的扩展主要是3个方面)的更多相关文章
- Qt编译mysql以及创建表后进行导入操作
鉴于很多同学对Qt编译myql总是不能成功.出现各种问题,今天特此写出本教程,希望可以帮到须要的同学. 首先,须要明确编译的目的和原理. 目的:Qt 5.2版本号曾经都是不带mysql驱 ...
- Linux编译安装Qt 5.4.1(-qt-xcb是必须要指定的,卸载自带的gcc等)
转载请注明文章:Linux编译安装Qt 5.4.1 出处:多客博图 很久不写文章了,过程很简单,但是操作很多,简单说吧. 前言: 操作系统CentOS 6.6,64位的. 1.安装gcc 4.8.4, ...
- QT编译./configure参数的详细解释
可以随便的转载,只要按照规矩走带上咱论坛的链接就好. ======================================全文是按照./configure -help来翻译的========= ...
- Qt编译安装qwt错误moc/xxx Error:126
最近搞设计,需要在上位机上绘制曲线,在网上找了找,发现python的matplotlib和Qt的qwt都不错,本着难度最小原则,选择了Qt下面的qwt,安装过程中遇到了编译错误:moc/xxx Err ...
- osg,qt编译的一些问题
osg编译例子的时候,打开文件就出问题,可能是一些不兼容的问题 qt编译的是时候要添加qt和vs2010的整合工具,这样才能把 vs2010里面的QTDIR变量和环境变量QTDIR关联起来 同是右击文 ...
- VS2010 win7 QT4.8.0,实现VS2010编译调试Qt程序,QtCreator静态发布程序
下载源代码,注意一定是源码压缩包如qt-everywhere-opensource-src-4.8.0.zip, 不是Qt发布的已编译的不同版本的标准库如qt-win-opensource-4.8.0 ...
- Solaris 10下Qt编译Oracle 10g驱动
上回书讲到<Oracle 10g在Solaris 10中安装详解>,现在开始用Qt来编译下Oracle 10g驱动吧!这样就可以通过Qt程序联入Oracle数据库了! Oracle的环境变 ...
- Qt编译安装后中文无法显示问题
闲的蛋疼,把Ubuntu删了,再装10.04的时候,QT编译后运行自己的程序已经不能显示中文了,只能显示英文,字体贼丑... 想了各种办法,都没解决.. 最后:终于搞定: apt-get instal ...
- 在CentOS下面编译WizNote Qt Project
编译环境 CentOS 64位 Desktop 版本:6.5 编译前的准备: CentOS的用户默认没有root权限,如果当前用户没有权限root,则可以在终端里面执行下面的命令: su root s ...
随机推荐
- map_multimap
#include<iostream> #include<string> #include<map> using namespace std; struct Self ...
- Spark RDD :Spark API--Spark RDD
一.RDD的概述 1.1 什么是RDD? RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变.可分区.里面的元素 ...
- jquery ajax请求数据超时设置
var ajaxTimeoutTest = $.ajax({ url:'', //请求的URL timeout : 1000, //超时时间设置,单位毫秒 type : 'get', //请求方式,g ...
- Spring boot jpa 设定MySQL数据库的自增ID主键值
内容简介 本文主要介绍在使用jpa向数据库添加数据时,如果表中主键为自增ID,对应实体类的设定方法. 实现步骤 只需要在自增主键上添加@GeneratedValue注解就可以实现自增,如下图: 关键代 ...
- mssql 清理死锁
-存储过程 我们可以使用以下存储过程来检测,就可以查出引起死锁的进程和SQL语句.SQL Server自带的系统存储过程sp_who和sp_lock也可以用来查找阻塞和死锁, 但没有这里介绍的方法好用 ...
- api的url规则设计,带参数的路由
api的url设计规则 router := gin.Default() router.GET("/topic/:topic_id", func(context *gin.Conte ...
- JavaScript基础03——函数的作用域及变量提升
1.作用域 作用域,变量在函数内部作用的范围/区域.有函数的地方就有作用域. 2.局部作用域和全局作用域 function fn(){ var a = 1; } console.log(a); / ...
- WinDbg常用命令系列---|(进程状态)
|(进程状态) 简介 (|) 命令显示指定进程的状态或当前正在调试你的所有进程. 使用形式 | Process 参数 Process 指定要显示的进程. 如果省略此参数,将显示所有正在调试的进程. 支 ...
- virtualenvwrapper 方便的virtualenv 包装
virtualenvwrapper 是一个方便的virtualenv 包装我们可以用来方便的管理python 的开发环境,同时 也支持对于项目的管理 安装 pip 安装 pip install v ...
- BMP文件格式详解(BMP file format)
BMP文件格式,又称为Bitmap(位图),或是DIB(Device-Independent Device,设备无关图),是windows系统中广泛使用的图片文件格式,由于它可以不作任何变换地址保存图 ...