沉沉的黑夜都是白天的前奏。——郭小川


舍弃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

最新文章

  1. 关于/etc/rc.local以及/etc/init.d
  2. 【BZOJ-3956】Count ST表 + 单调栈
  3. 使用PDO进行sql的预处理和操作结果集
  4. springmvc03 非注解和注解处理器映射器和适配器
  5. C语言计算程序运行时间
  6. 单页应用引擎的写法artTemplate
  7. 使用 getNextException() 来检索已经过批处理的特定元素的异常。 ERRORCODE=-4228, SQLSTATE=null
  8. 【HDOJ】3459 Rubik 2&#215;2&#215;2
  9. Python 类继承,__bases__, __mro__, super
  10. docker中管理数据
  11. [Hadoop] - 自定义Mapreduce InputFormat&amp;OutputFormat
  12. 每篇半小时1天入门MongoDB——3.MongoDB可视化及shell详解
  13. 手淘的flexible.js解决手机适配问题
  14. PyCharm链接服务器同步代码
  15. android使用JSON数据和服务器进行交互
  16. 学习安卓开发[4] - 使用隐式Intent启动短信、联系人、相机应用
  17. oracle to_char 格式大全
  18. Spring中的@Transactional(rollbackFor = Exception.class)属性详解
  19. Skip the Class
  20. HDU 3338 Kakuro Extension (网络流,最大流)

热门文章

  1. django-改写manage类-objects
  2. AOP_原理
  3. sort()函数中的key
  4. [Codeforces 1251F]Red-White Fence
  5. 使用SpringBoot访问jsp页面
  6. 4个MySQL优化工具AWR,帮你准确定位数据库瓶颈!(转载)
  7. 【JZOJ6218】【20190615】卖弱
  8. 关于移动虚拟机后,linux网卡启动异常问题解决
  9. Tkinter 之爬虫框架项目实战
  10. python 安装离线库