Qt5的widget项目文件解析

时间:2022-01-24 23:11:11

本文将以一个最简单的HelloWorld程序为例,解析Qt5项目各文件的内容及功能。供初学者简单了解基于Qt5的widget程序架构。


HelloWorld-┌HelloWorld.pro

                    ├─ HelloWorld.pro.user

                    ├─ main.cpp

                    ├─ hellodialog.ui

                    ├─ hellodialog.h

                    ─ hellodialog.cpp


注:还有两个文件,在初次编译后会在编译目录中生成。

                    ├─HelloWorld.rc

                    └─ ui_hellodialog.h


1. pro文件


#-------------------------------------------------
#
# Project created by QtCreator 2016-09-29T13:46:35
#
#-------------------------------------------------

QT += core gui #表明Qt使用的模块。core:非图形界面的核心功能模块,gui:图形界面功能模块。

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets #表示Qt4之后的版本还需要再包含widgets模块。

TARGET = HelloWorld #目标exe的文件名。
TEMPLATE = app #目标模板类型。app表示应用程序模板。


SOURCES += main.cpp\ #表示项目包含的源文件、头文件、界面文件
hellodialog.cpp

HEADERS += hellodialog.h

FORMS += hellodialog.ui

RC_FILE = HelloWorld.rc #添加资源文件



注:将程序编译一次后,在编译目录会生成一个.rc文件,此文件定义程序的版本号、图标等信息。将它拷贝到源代码目录,并在pro文件中进行包含即可。


本例为HelloWorld.rc。


# if defined(UNDER_CE)                                                          //选择是否在WinCE环境
# include <winbase.h>
# else
# include <windows.h>
# endif

IDI_ICON1 ICON DISCARDABLE "myappico.ico" //定义应用程序的图标

VS_VERSION_INFO VERSIONINFO //定义应用程序的版本号
FILEVERSION 1,0,0,0 //文件版本号
PRODUCTVERSION 0,0,0,0 //产品版本号
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS VS_FF_DEBUG
#else
FILEFLAGS 0x0L
#endif
FILEOS VOS__WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "\0" //公司名称
VALUE "FileDescription", "\0" //文件描述
VALUE "FileVersion", "1.0.0.0\0" //文件版本号
VALUE "LegalCopyright", "\0" //版权声明
VALUE "OriginalFilename", "HelloWorld.exe\0" //文件名
VALUE "ProductName", "HelloWorld\0" //产品名称
VALUE "ProductVersion", "1.0.0.0\0" //产品版本号
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0409, 1200
END
END
/* End of Version info */



2. user文件


包含Qt版本和构建目录信息等的文件,可删除。


3. main.cpp


#include "hellodialog.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv); //任何Qt应用都要包含一个QApplication对象,代表应用本身。且QApplication必须先于其他所有的Qt对象进行构造。
HelloDialog w;
w.show();

return a.exec(); //进入消息循环
}


4. hellodialog.ui


xml文件,描述窗口部件及其布局信息。


补充:Qt在编译时,将.ui文件中的界面描述转换为各种部件类、布局类等,并生成了一个界面类,命名为ui_***.h(声明和定义同时进行,都在头文件中),放在了编译目录中。实际由此.h文件参与编译。widget类hellodialog继承了这个类。


本例为ui_hellodialog.h。


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

#ifndef UI_HELLODIALOG_H
#define UI_HELLODIALOG_H

#include <QtCore/QVariant> //包含界面相关的头文件
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QLabel>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE //命名空间开始宏

class Ui_HelloDialog //定义的类将实现各部件的创建、布局,以及信号槽的关联等
{
public:
QLabel *label;

void setupUi(QWidget *HelloDialog) //将一个widget关联此类。如果ui文件定义的是Dialog或MainWindow类型,则此处指针类型也会不一样
{
if (HelloDialog->objectName().isEmpty())
HelloDialog->setObjectName(QStringLiteral("HelloDialog")); //设置对话框的对象名称
HelloDialog->resize(400, 137); //设置窗口大小
label = new QLabel(HelloDialog); //定义一个QLabel对象
label->setObjectName(QStringLiteral("label")); //设置QLabel的属性
label->setGeometry(QRect(170, 60, 101, 16));

retranslateUi(HelloDialog); //对窗口涉及到的字符串进行编码转换。是类的另外一个成员函数。

QMetaObject::connectSlotsByName(HelloDialog); //允许此部件通过名称与槽自动连接
} // setupUi

void retranslateUi(QWidget *HelloDialog) //对窗口涉及到的字符串进行编码转换
{
HelloDialog->setWindowTitle(QApplication::translate("HelloDialog", "HelloDialog", 0));
label->setText(QApplication::translate("HelloDialog", "Hello World!", 0));
} // retranslateUi

};

namespace Ui {
class HelloDialog: public Ui_HelloDialog {}; //在Ui名称空间中声明一个从ui类继承的类。在widget中将包含此类的指针
} // namespace Ui

QT_END_NAMESPACE //命名空间结束宏

#endif // UI_HELLODIALOG_H



5. hellodialog.h


主窗口类(widget)头文件。


#ifndef HELLODIALOG_H
#define HELLODIALOG_H

#include <QWidget>

namespace Ui {
class HelloDialog; //根据.ui文件生成的类的派生类。此处做前置声明
}

class HelloDialog : public QWidget //widget类
{
Q_OBJECT

public:
explicit HelloDialog(QWidget *parent = 0); //构造函数
~HelloDialog(); //析构函数

private:
Ui::HelloDialog *ui; //根据.ui文件生成的类的派生类指针。通过ui文件定义的部件,可以通过这个指针来访问
};

#endif // HELLODIALOG_H




6. hellodialog.cpp


主窗口类(widget)源文件。



#include "hellodialog.h"
#include "ui_hellodialog.h"

HelloDialog::HelloDialog(QWidget *parent) :
QWidget(parent),
ui(new Ui::HelloDialog) //在构造函数中实例化由.ui文件定义的界面类的派生类
{
ui->setupUi(this); //将.ui文件定义的界面类的派生类与此widget类关联起来
}

HelloDialog::~HelloDialog()
{
delete ui; //在析构函数中释放由.ui文件定义的界面类的派生类实例
}