深入理解Qt 初始项目代码

 更新时间:2025年02月28日 10:32:47   作者:Yui_  
本文解析了Qt项目创建后的主要文件,包括main.cpp、mywidget.h、mywidget.cpp、mywidget.ui和.pro,main.cpp这五个文件,具有一定的参考价值,感兴趣的可以了解一下

当创建完项目时看到这样的界面:

image.png

本文将聚焦与项目创建后的这5个文件的解析,这5个文件分别为: test250225mywidget.hmain.cppmywidget.cppmywidget.ui
现在开始逐个解析

1. main.cpp内容解析

#include "mywidget.h"

#include <QApplication>

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

该函数中的QApplication a这是编写Qt图形化界面一定需要的对象,它的作用为:

  • 应用程序的初始化
  • 事件循环管理
  • 窗口管理
  • GUI相关功能
  • 全局资源管理
    在 Qt Widgets 应用程序中,通常必须创建 QApplication 对象,否则 GUI 组件无法正常工作。

继续往下看,MyWidget是创建项目时,填写的类名。
w.show()的作用是创建一个控件对象,并显示出来,同时你还可以用.hide()让控件隐藏,注意Wight的父类是QWightWight中的方法大部分都是继承至父类。

然后我们来看a.exec()这个有没有很熟悉,如果你学过Linux,在Linux中有一个进程程序替换的函数,确切来说是6个函数,他们是一个系列,可以把可执行文件中的代码和数据替换到当前进程中。
是不是觉得他们有什么关系呢?
完全没有如何关系!!!
只是名字一样而已,就像家豪这个名字,可能你遇到过几个家豪,只是名字一样而已。
在计算机的世界,这种情况并不少见,你还能想到其他例子吗?
你肯定想到了计算机中的栈和堆了吧,有数据结构中的栈和堆,还有操作系统中的栈和堆甚至还有JVM中的栈和堆,这3种栈和堆都有不同的概念,但是他们的名字相同。
主函数介绍完了,我们开始介绍其他文件。

2. mywidget.h内容解析

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class MyWidget; }
QT_END_NAMESPACE

class MyWidget : public QWidget//继承父类
{
    Q_OBJECT//宏替换

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

private:
    Ui::MyWidget *ui;
};
#endif // MYWIDGET_H

先看这段代码:

QT_BEGIN_NAMESPACE
namespace Ui { class MyWidget; }
QT_END_NAMESPACE

其中QT_BEGIN_NAMESPACE和QT_END_NAMESPACE是Qt提供的命名空间宏。
namespace Ui { class MyWidget; }是一种向前声明,用于声明UI::MyWidget这个类。

在这里我们主要还是关注这个类,这个类就是我们创建项目时所命名的,可以看到它确实继承至QWight我们可以看到类中存在着一个宏,Q_OBJECT是Qt中一个内置的宏,宏本质上就是文本替换,其实它会替换为一大堆代码。
跳转过去看看:

image.png

看不懂。。。
Qt中有一个非常核心的机制,“信号和槽”,如果某个类想要使用"信号和槽"就需要引入这个宏。
在往下看,就是构造函数和析构函数,析构函数没什么好讲的,我们看到构造函数,构造函数的形参是一个QWidget类型的缺省。
这里其实存在着一个Qt中引入的对象树机制(目前不解释)。
创建的Qt对象可把这个对象给挂到对象树上,往树上挂的时候就需要指定父节点(这里的树是n叉树)

3. mywidget.cpp内容解析

#include "mywidget.h"//创建项目生成的头文件
#include "ui_mywidget.h"//form file被qmake生成的头文件

MyWidget::MyWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MyWidget)
{
    ui->setupUi(this);//把form file生成的界面和当前widget关联起来
}

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

image.png

4. form file内容解析

双击文件mywidget.ui文件

image.png

会进入设计界面

image.png

左边是Qt内置的1控件,可以直接拖拽到右边的程序窗口,没错我们还可以这样创建出具体的界面。每个控件都有很多属性,我们可以自行设计控件的属性

点击左侧栏的编辑按钮,此时显示的内容,就是.ui文的本体了

image.png

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MyWidget</class>
 <widget class="QWidget" name="MyWidget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MyWidget</string>
  </property>
 </widget>
 <resources/>
 <connections/>
</ui>

看到这个格式有没有一点熟悉,有点像html的标签模式,但是呢这个格式被称为xml格式
xml这里的标签是可以程序员自定义的,有点类似于网络中的自定义应用层协议。而html的标签是由标准委员会约定的,所有的浏览器也是按照约定来解释的
Qt中使用xml文件就是描述程序的界面是啥样的,再进一步的qmake文件会调用相关的工具依据这个xml文件生成一些C++代码,从而把完整的界面构造出来。

5. .pro内容解析

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

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.
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.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    mywidget.cpp

HEADERS += \
    mywidget.h

FORMS += \
    mywidget.ui

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

现在看到.pro Qt的工程文件,也是qmake工具构建的重要依据,注意:.pro类似Linux中的makefile文件是一个自动化构建工具
直接看总结版:

部分作用
QT += core gui添加 QtCore 和 QtGui 模块(基础功能和 GUI 支持)。
QT += widgetsQt 5+ 需要额外添加 QtWidgets 以使用 QWidget。
CONFIG += c++11启用 C++11 语法支持。
DEFINES += QT_DEPRECATED_WARNINGS启用 Qt 过时 API 的警告。
SOURCES += main.cpp mywidget.cpp指定 .cpp 源文件。
HEADERS += mywidget.h指定 .h 头文件。
FORMS += mywidget.ui指定 Qt Designer 的 .ui 文件。
target.path设置不同平台的安装路径。
image.png

红框中的内容是描述当前项目中,参与构建的文件都有什么,这地方不需要手动修改,qt Creator会帮我们自动维护好。
上面我们看到的都是源代码,其实在编译运行中还会产生一些中间文件。

打开文件自愿管理器,看看项目对应的目录是什么样子~

image.png

image.png

在运行一次程序后,就会在项目并列的地方多出来一个buildxxx目录
这个目录是用来存储运行过程中的临时文件的。

image.png

打开目录,看到了一个makefile文件,看来编译Qt程序还是会用到makefile文件啊,由qmake自动生成。
然后我们,再看到ui_mywidget.h文件,该文件是根据前面的xml文件自动生成的,打开ui_mywidget.h文件:

/********************************************************************************
** Form generated from reading UI file 'mywidget.ui'
**
** Created by: Qt User Interface Compiler version 5.14.0
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_MYWIDGET_H
#define UI_MYWIDGET_H

#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_MyWidget
{
public:

    void setupUi(QWidget *MyWidget)
    {
        if (MyWidget->objectName().isEmpty())
            MyWidget->setObjectName(QString::fromUtf8("MyWidget"));
        MyWidget->resize(800, 600);

        retranslateUi(MyWidget);

        QMetaObject::connectSlotsByName(MyWidget);
    } // setupUi

    void retranslateUi(QWidget *MyWidget)
    {
        MyWidget->setWindowTitle(QCoreApplication::translate("MyWidget", "MyWidget", nullptr));
    } // retranslateUi

};

namespace Ui {
    class MyWidget: public Ui_MyWidget {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_MYWIDGET_H

6. 总结

总结来说,Qt 初始代码的结构清晰且模块化,充分体现了 Qt 框架的设计哲学。从 QApplication 的初始化到 QWidget 的父子管理机制,再到 .pro 文件的配置,每个部分都在确保应用的稳定性和可扩展性。理解这些基础代码,不仅有助于掌握 Qt 的事件循环、窗口管理和资源组织方式,还能为后续的开发打下坚实的基础。希望这篇解析能帮助你更高效地入门 Qt,并为更复杂的应用开发做好准备。

到此这篇关于深入理解Qt 初始项目代码的文章就介绍到这了,更多相关Qt 初始项目代码内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • socket多人聊天程序C语言版(一)

    socket多人聊天程序C语言版(一)

    这篇文章主要为大家详细介绍了socket多人聊天程序C语言版,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10
  • 基于Qt播放器的实现详解(支持Rgb,YUV格式)

    基于Qt播放器的实现详解(支持Rgb,YUV格式)

    这篇文章主要为大家详细介绍了如何利用Qt实现简易的播放器,可以支持支持Rgb,YUV格式。文中的示例代码讲解详细,感兴趣的小伙伴可以尝试一下
    2022-12-12
  • C语言详解如何实现堆及堆的结构与接口

    C语言详解如何实现堆及堆的结构与接口

    堆是计算机科学中一类特殊的数据结构的统称,通常是一个可以被看做一棵完全二叉树的数组对象。而堆排序是利用堆这种数据结构所设计的一种排序算法。本文将详细介绍堆的结构与接口,需要的可以参考一下
    2022-04-04
  • C++ 将一个文件读入数组再读出数组的方法

    C++ 将一个文件读入数组再读出数组的方法

    今天小编就为大家分享一篇C++ 将一个文件读入数组再读出数组的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • c++项目中后缀名vcxproj和sln的区别及说明

    c++项目中后缀名vcxproj和sln的区别及说明

    这篇文章主要介绍了c++项目中后缀名vcxproj和sln的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05
  • 探讨:程序在内存中的分配(常量,局部变量,全局变量,程序代码)问题

    探讨:程序在内存中的分配(常量,局部变量,全局变量,程序代码)问题

    本篇文章是对程序在的内存中分配(常量,局部变量,全局变量,程序代码)的问题进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C++使用一棵红黑树同时封装出map和set实例代码

    C++使用一棵红黑树同时封装出map和set实例代码

    红黑树(Red Black Tre)是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组,下面这篇文章主要给大家介绍了关于C++使用一棵红黑树同时封装出map和set的相关资料,需要的朋友可以参考下
    2023-04-04
  • C语言连续生成随机数的实现方法

    C语言连续生成随机数的实现方法

    这篇文章主要介绍了C语言连续生成随机数的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • C语言实现简单图书管理系统

    C语言实现简单图书管理系统

    这篇文章主要为大家详细介绍了C语言实现图书管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • C++实现调用系统时间简单示例

    C++实现调用系统时间简单示例

    这篇文章主要介绍了C++实现调用系统时间,需要的朋友可以参考下
    2014-07-07

最新评论