我是靠谱客的博主 超级大船,最近开发中收集的这篇文章主要介绍Qt第一解:新建项目和基础代码解析New Project基础代码编译成果验证,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

QtCreator新建项目

  • New Project
    • 项目路径
    • make工具
    • 文件命名和基础窗口
    • 工具包
  • 基础代码
    • 文件组成
    • .h(头文件)
    • .cpp(源文件)
    • main.cpp
    • .pro(工程文件)
  • 编译成果验证

工欲善其事,必先利其器
—《论语·魏灵公》

C++好像也只有这个玩意可以实践了。

新建一个项目文件,一步步来。

New Project

在这里插入图片描述

项目路径

存放项目文件的地方,不做概述
在这里插入图片描述

make工具

make指的是编译方式,一般分为make,qmake,cmake,qbs等等方式,考虑到项目中文件的相互依存性,他的作用就是将你的所有文件打包一起运行

我们一般运行一个cpp文件是g++,如果要运行这个cpp文件的其他多个依赖文件进行多个步骤进行编译,需写一个makefile文件,里面存放着编译规则
在这里插入图片描述

文件命名和基础窗口

Class name:类名
Base class:基类

  • QMainWindow:带有工具栏的窗口
  • QWidget:最基础的窗口
  • QDialog:带有对话框窗口

Header file:头文件名(.h)
Source file:资源文件,一般填写.cpp文件名,后面还可以加入其他文件,如图片,字体等等。
Form file:ui文件名(Generate file表示是否创建该文件)
在这里插入图片描述

工具包

其实就是要用到的包含编译器的一个工具包的名称,此处为MinGW,分为32bit和64bit,大家根据自己电脑抉择
在这里插入图片描述

基础代码

文件组成

按照前面创建项目的过程,一个项目分为:Header文件夹,Source文件夹,u文件i和一个.pro文件

.pro文件即project,其中包含的是对整个项目的信息和操作控制

在这里插入图片描述

.h(头文件)

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

// 引入QMainWindow标准库
#include <QMainWindow>

// 类MainWindow继承自QMainWindow
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
	// 类内声明单参数构造函数,其中QWidget*类型参数parent置为空
    MainWindow(QWidget *parent = nullptr);
    // 类内声明析构函数
    ~MainWindow();
};
#endif // MAINWINDOW_H

在此不得不提一下Q_OBJECT这个宏,在Qt中有一种重要的机制是元对象系统(Meta-Object System)

槽与信号机制会自动帮我们生成部分代码,比如我们写的信号函数就不需要写它的实现部分,这是因为在我们编译程序的时候,编译器会自动生成这一部分代码,当我们调用connect函数的时候,系统会自动将信号函数与槽函数相连接,于是当我们调用信号函数的时候,系统就会自动回调槽函数,不管你是在同一线程下调用或者在不同线程下调用,系统都会自动评估,并在合理的时候触发函数,以此来保证线程的安全。信号与槽机制是线程安全的,这可以使得我们在调用的时候不用再额外的增加过多保证线程同步的代码,为了实现元对象系统,QT把所有相关实现写在了QObject类中,所以当你想使用元对象系统的时候,你所写的类需要继承自QObject,包括QT自带的所有类都是继承自QObject

其源码

#define Q_OBJECT 
public: 
    QT_WARNING_PUSH 
    Q_OBJECT_NO_OVERRIDE_WARNING 
    static const QMetaObject staticMetaObject; 
    virtual const QMetaObject *metaObject() const; 
    virtual void *qt_metacast(const char *); 
    virtual int qt_metacall(QMetaObject::Call, int, void **); 
    QT_TR_FUNCTIONS 
private: 
    Q_OBJECT_NO_ATTRIBUTES_WARNING 
    Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); 
    QT_WARNING_POP 
    struct QPrivateSignal {}; 
QT_ANNOTATE_CLASS(qt_qobject, "")

你可以看到这个宏定义了一些函数,并且函数名都带有meta,所以不难猜到这些函数和QT的元对象系统是有关系的,实际上你在qobject.cpp里面是找不到这些函数的实现的,它们的实现都在moc_qobject.cpp里面。QT的元对象系统是这样处理的,当你编译你的工程时,它会去遍历所有C++文件,当发现某一个类的私有部分有声明Q_OBJECT这个宏时,就会自动生成一个moc_.cpp的文件,这个文件会生成信号的实现函数,Q_OBJECT宏里面定义的那些函数也会在这个文件里面实现,并生成与类相关的元对象。这就是为什么我们定义一个信号的时候,不需要实现它,因为它的实现已经写在moc_*.cpp文件里面了。

更多可参考元数据系统

.cpp(源文件)

// 引入头文件
#include "mainwindow.h"
// 构造函数
/* 此处是显示调用基类对象,此处基类QMainWindow的实例化参数变成了parent
*/
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    
}
// 析构函数
MainWindow::~MainWindow()
{
}

main.cpp

// 引入头文件
#include "mainwindow.h"
// 引入应用程序标准库
#include <QApplication>

int main(int argc, char *argv[])
{
	// 创建一个应用程序对象a,参数为argc和argv
	// 这两个参数是C语言的内容,可自行查看
    QApplication a(argc, argv);
    // 创建一个类MainWindow的对象w
    MainWindow w;
    // 显示w
    w.show();
    // exec()可以类似的看似于Linux下从运行进程
    // 当我们w.show()一个应用程序后,运行这个进程
    // 除非我们按右上角的"X",可以看作是exit(0),结束这个进程
    // 否则这个窗口会持续的显示,即进程不断
    return a.exec();
}

.pro(工程文件)

# 使用QT的core的gui库,即Qt的专用可视化库
QT       += core gui

# Qt5里不再用QtGui模块,而是使用QtWidgets模块
# 如果QT主版本大于4(也就是说当前使用的是Qt5或者更高版本),则需要添加widgets模块。
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

# c++的版本
CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.

# 如果你使用了任何Qt曾经标记为不支持的特性,下面这个定义让你的编译器发出危险信号(取决于你的编译器),请看相关不支持特性的文档为了提高你代码的质量
DEFINES += QT_DEPRECATED_WARNINGS


# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
# 你也可以让你的代码编译失败如果他使用不支持的特征,为了这么做,取消下面的注解即可;
# 你也可以选择卸载不支持的API去使用Qt的特定版本
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

# 资源文件夹下的文件
SOURCES += 
    main.cpp 
    mainwindow.cpp
    
# 头文件夹下的文件
HEADERS += 
    mainwindow.h

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

编译成果验证

来看编译成功的文件夹,分成两个,一个是源文件夹,一个是编译后的文件夹
在这里插入图片描述
编译后的文件夹分为三部分:release,debug和其他文件:
在这里插入图片描述

  • 其他文件,可知都是makefile文件,即qmake工具生成的文件进行工程项目文件自动化编译
  • debubg和release:资源文件夹中的两个.cpp文件生成的对象文件(.o),一个在Windows下的可执行文件(.exe);一个元对象系统即O_OBJECT机制形成的元对象源文件(.cpp)和元对象源文件的对象文件(.o),是自动生成的

一个是debug模式,一个是release模式,两种模式有区别,在此不做概述(一般默认是debug模式)

来看看moc*.cpp元对象源文件

/****************************************************************************
** Meta object code from reading C++ file 'mainwindow.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.12.6)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/

#include "../../test/mainwindow.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'mainwindow.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.12.6. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif

QT_BEGIN_MOC_NAMESPACE
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
struct qt_meta_stringdata_MainWindow_t {
    QByteArrayData data[1];
    char stringdata0[11];
};
#define QT_MOC_LITERAL(idx, ofs, len) 
    Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, 
    qptrdiff(offsetof(qt_meta_stringdata_MainWindow_t, stringdata0) + ofs 
        - idx * sizeof(QByteArrayData)) 
    )
static const qt_meta_stringdata_MainWindow_t qt_meta_stringdata_MainWindow = {
    {
QT_MOC_LITERAL(0, 0, 10) // "MainWindow"

    },
    "MainWindow"
};
#undef QT_MOC_LITERAL

static const uint qt_meta_data_MainWindow[] = {

 // content:
       8,       // revision
       0,       // classname
       0,    0, // classinfo
       0,    0, // methods
       0,    0, // properties
       0,    0, // enums/sets
       0,    0, // constructors
       0,       // flags
       0,       // signalCount

       0        // eod
};

void MainWindow::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
    Q_UNUSED(_o);
    Q_UNUSED(_id);
    Q_UNUSED(_c);
    Q_UNUSED(_a);
}

QT_INIT_METAOBJECT const QMetaObject MainWindow::staticMetaObject = { {
    &QMainWindow::staticMetaObject,
    qt_meta_stringdata_MainWindow.data,
    qt_meta_data_MainWindow,
    qt_static_metacall,
    nullptr,
    nullptr
} };


const QMetaObject *MainWindow::metaObject() const
{
    return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}

void *MainWindow::qt_metacast(const char *_clname)
{
    if (!_clname) return nullptr;
    if (!strcmp(_clname, qt_meta_stringdata_MainWindow.stringdata0))
        return static_cast<void*>(this);
    return QMainWindow::qt_metacast(_clname);
}

int MainWindow::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    _id = QMainWindow::qt_metacall(_c, _id, _a);
    return _id;
}
QT_WARNING_POP
QT_END_MOC_NAMESPACE

这个其实就是前面O_OBJECT宏中相关数据的定义。

最后还有一个predefs.h文件,其中是一些相关宏的定义

#define __DBL_MIN_EXP__ (-1021)
#define __FLT32X_MAX_EXP__ 1024
#define __cpp_attributes 200809
#define __pentiumpro__ 1
#define __UINT_LEAST16_MAX__ 0xffff
#define __ATOMIC_ACQUIRE 2
#define __FLT128_MAX_10_EXP__ 4932
#define __FLT_MIN__ 1.17549435082228750796873653722224568e-38F
#define __GCC_IEC_559_COMPLEX 2
#define __UINT_LEAST8_TYPE__ unsigned char
#define __SIZEOF_FLOAT80__ 12
#define _WIN32 1
#define __INTMAX_C(c) c ## LL
#define __CHAR_BIT__ 8
...

最后

以上就是超级大船为你收集整理的Qt第一解:新建项目和基础代码解析New Project基础代码编译成果验证的全部内容,希望文章能够帮你解决Qt第一解:新建项目和基础代码解析New Project基础代码编译成果验证所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部