您现在的位置是:首页 >技术杂谈 >C/C++笔记-使用Qt的UI文件时make流程网站首页技术杂谈

C/C++笔记-使用Qt的UI文件时make流程

IT1995 2024-06-17 10:22:08
简介C/C++笔记-使用Qt的UI文件时make流程

首先创建如下项目:

QtWidgetMakfileDemo.pro

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += 
    main.cpp 
    Widget.cpp

HEADERS += 
    Widget.h

FORMS += 
    Widget.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

Widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

main.cpp

#include "Widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

Widget.cpp

#include "Widget.h"
#include "ui_Widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
}

Widget::~Widget()
{
    delete ui;
}

ui是空的。

此时运行命令qmake,然后再make,打印如下:

/opt/Qt5.5.1/5.5/gcc_64/bin/uic Widget.ui -o ui_Widget.h
g++ -c -pipe -O2 -std=c++0x -Wall -W -D_REENTRANT -fPIC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -I/opt/Qt5.5.1/5.5/gcc_64/include -I/opt/Qt5.5.1/5.5/gcc_64/include/QtWidgets -I/opt/Qt5.5.1/5.5/gcc_64/include/QtGui -I/opt/Qt5.5.1/5.5/gcc_64/include/QtCore -I. -I. -I/opt/Qt5.5.1/5.5/gcc_64/mkspecs/linux-g++ -o main.o main.cpp
g++ -c -pipe -O2 -std=c++0x -Wall -W -D_REENTRANT -fPIC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -I/opt/Qt5.5.1/5.5/gcc_64/include -I/opt/Qt5.5.1/5.5/gcc_64/include/QtWidgets -I/opt/Qt5.5.1/5.5/gcc_64/include/QtGui -I/opt/Qt5.5.1/5.5/gcc_64/include/QtCore -I. -I. -I/opt/Qt5.5.1/5.5/gcc_64/mkspecs/linux-g++ -o Widget.o Widget.cpp
/opt/Qt5.5.1/5.5/gcc_64/bin/moc -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I/opt/Qt5.5.1/5.5/gcc_64/mkspecs/linux-g++ -I/root/CffPro/QtWidgetMakefileDemo -I/opt/Qt5.5.1/5.5/gcc_64/include -I/opt/Qt5.5.1/5.5/gcc_64/include/QtWidgets -I/opt/Qt5.5.1/5.5/gcc_64/include/QtGui -I/opt/Qt5.5.1/5.5/gcc_64/include/QtCore Widget.h -o moc_Widget.cpp
g++ -c -pipe -O2 -std=c++0x -Wall -W -D_REENTRANT -fPIC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -I/opt/Qt5.5.1/5.5/gcc_64/include -I/opt/Qt5.5.1/5.5/gcc_64/include/QtWidgets -I/opt/Qt5.5.1/5.5/gcc_64/include/QtGui -I/opt/Qt5.5.1/5.5/gcc_64/include/QtCore -I. -I. -I/opt/Qt5.5.1/5.5/gcc_64/mkspecs/linux-g++ -o moc_Widget.o moc_Widget.cpp
g++ -Wl,-O1 -Wl,-rpath,/opt/Qt5.5.1/5.5/gcc_64 -Wl,-rpath,/opt/Qt5.5.1/5.5/gcc_64/lib -o QtWidgetMakefileDemo main.o Widget.o moc_Widget.o   -L/opt/Qt5.5.1/5.5/gcc_64/lib -lQt5Widgets -L/usr/lib64 -lQt5Gui -lQt5Core -lGL -lpthread 

整体逻辑是这样的:

①将ui文件生成对应的C++的.h文件;

②将.cpp编译成.o文件;

③将带有Q_OBJECT和继承了QObject的类生成对应的moc_xxx.cpp文件;

④编译moc文件,生成对应的.o文件;

⑤链接所有.o文件以及动态库,生成可执行程序;

下面来分析下每个步骤:

/opt/Qt5.5.1/5.5/gcc_64/bin/uic Widget.ui -o ui_Widget.h

各个参数分析:

调用uic程序,将ui文件生成对应的ui_widget.h文件;

g++ -c -pipe -O2 -std=c++0x -Wall -W 
-D_REENTRANT -fPIC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB 
-I. 
-I/opt/Qt5.5.1/5.5/gcc_64/include 
-I/opt/Qt5.5.1/5.5/gcc_64/include/QtWidgets 
-I/opt/Qt5.5.1/5.5/gcc_64/include/QtGui 
-I/opt/Qt5.5.1/5.5/gcc_64/include/QtCore 
-I. 
-I. 
-I/opt/Qt5.5.1/5.5/gcc_64/mkspecs/linux-g++ 
-o main.o main.cpp

各个参数分析:

-c:生成文件;

-pipe:在不同的编译阶段使用管道替代临时文件;

-O2:optimization优化,比-O高一级的优化,编译优化,具体优化哪些内容,在此不说明;

-std=c++0x:指定c++版本;

-Wall:编译后显示所有告警;

-W:默认报警也要显示;

-D_REENTRANT:它会对部分函数重新定义它们的可安全重入的版本;

-fPIC:用于生成位置无关的代码(Position-Independent-Code);

-DQT_NO_DEBUG:这个没查到,但看名称差不多能猜到是QT不使用Debug;

-DQT_CORE_LIB:这个没查到,但看名称差不多能猜到是QT核心库;

-DQT_GUI_LIB:这个没查到,但看名称差不多能猜到是QT的图形GUI库;

-I:表示包含的include文件;

-o:表示编译成object文件。

g++ -c -pipe -O2 -std=c++0x -Wall -W 
-D_REENTRANT -fPIC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB 
-I. 
-I/opt/Qt5.5.1/5.5/gcc_64/include 
-I/opt/Qt5.5.1/5.5/gcc_64/include/QtWidgets 
-I/opt/Qt5.5.1/5.5/gcc_64/include/QtGui 
-I/opt/Qt5.5.1/5.5/gcc_64/include/QtCore 
-I. 
-I. 
-I/opt/Qt5.5.1/5.5/gcc_64/mkspecs/linux-g++ 
-o Widget.o Widget.cpp

各个参数分析:

和②步一样。

/opt/Qt5.5.1/5.5/gcc_64/bin/moc -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB 
-I/opt/Qt5.5.1/5.5/gcc_64/mkspecs/linux-g++ 
-I/root/CffPro/QtWidgetMakefileDemo 
-I/opt/Qt5.5.1/5.5/gcc_64/include 
-I/opt/Qt5.5.1/5.5/gcc_64/include/QtWidgets 
-I/opt/Qt5.5.1/5.5/gcc_64/include/QtGui 
-I/opt/Qt5.5.1/5.5/gcc_64/include/QtCore Widget.h 
-o moc_Widget.cpp

各个参数分析:

和②步一样。

从中发现了个有意思的,以前都以为moc_xxx.cpp文件是通过对于的.h和.cpp使用moc联合生成的,现在发现他仅仅是使用对应的.h文件生成。具体moc_Wiget.cpp文件的内容在后面说明。

g++ -c -pipe -O2 -std=c++0x -Wall -W -D_REENTRANT 
-fPIC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB 
-I. 
-I/opt/Qt5.5.1/5.5/gcc_64/include 
-I/opt/Qt5.5.1/5.5/gcc_64/include/QtWidgets 
-I/opt/Qt5.5.1/5.5/gcc_64/include/QtGui 
-I/opt/Qt5.5.1/5.5/gcc_64/include/QtCore 
-I. 
-I. 
-I/opt/Qt5.5.1/5.5/gcc_64/mkspecs/linux-g++ 
-o moc_Widget.o moc_Widget.cpp

各个参数分析:

和②步一样。

这里就很明确的发现了,在编译阶段,使用了Q_OBJECT和继承了QObject的类会编译时会生成2个object文件,分别是原始object和带moc的object文件。

g++ -Wl,-O1 -Wl,-rpath,/opt/Qt5.5.1/5.5/gcc_64 
-Wl,-rpath,/opt/Qt5.5.1/5.5/gcc_64/lib 
-o QtWidgetMakefileDemo main.o Widget.o moc_Widget.o   
-L/opt/Qt5.5.1/5.5/gcc_64/lib 
-lQt5Widgets 
-L/usr/lib64 -lQt5Gui -lQt5Core -lGL -lpthread 

各个参数分析:

-Wl, -rpath:①用于编译时指定间接引用的库位置,作用同-Wl,-rpath-link;②用于运行时指定所有引用库的位置,作用同修改环境变量(LD_LIBRARY_PATH),并且库路径引用优先级高于LD_LIBRARY_PATH;

-L:Link链接路径;

-l:链接到哪个so文件。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。