跳至主要內容

QT

LincZero大约 4 分钟

QT

目录

开发流程 - 观察(项目结构)

项目结构

注:QtCreator的项目浏览器的顶部有个筛选器,可以简化树形结构(不区分头文件/源文件/ui文件)

  • ProjectName项目名
    • ProjectName.pro,项目文件
    • Headers头文件
      • widget.h/mainwindow.h/dialog.h,窗口类的头文件
    • Sources源文件
      • main.cpp,入口文件
      • widget.cpp/mainwindow.cpp/dialog.cpp,窗口类,继承的是QWidget.cpp/QMainWindow.cpp/QDialog.cpp
    • Forms
      • .ui,窗口布局文件

demo项目文件

main.cpp(入口文件)

代码

#include "widget.h"                 // 窗口类的头文件

#include <QApplication>

int main(int argc, char *argv[])    // 程序入口,argc是命令行变量的数量,argv是命令行变量的数组
{
    QApplication a(argc, argv);     // a是应用程序的实例对象。在Qt中该应用程序对象有且只有一个
    Widget w;                       // 窗口类的实例对象
    w.show();                       // 显示窗口
    return a.exec();                // 进入消息循环
}

widget.h(窗口类的头文件)

代码

#ifndef WIDGET_H                        // 防止头文件重复包含-1
#define WIDGET_H                        // 防止头文件重复包含-2

#include <QWidget>                      // 预编译 QWidget窗口类

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }          // 前置声明ui生成文件中的Ui::Widget类
QT_END_NAMESPACE

class Widget : public QWidget           // 继承QWidget窗口类
{
    Q_OBJECT                            // Q_OBJECT宏,允许类中使用信息好槽的机制

public:
    Widget(QWidget *parent = nullptr);  // 构造函数
    ~Widget();                          // 析构函数

private:
    Ui::Widget *ui;                     // .ui后生成一个.h,里面有一个UI_MainWindow类,Ui::MainWindow继承于UI_MainWindow类
};
#endif // WIDGET_H                      // 防止头文件重复包含-3

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }		// 前置声明ui生成文件中的Ui::MainWindow类
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private:
    // 私有指针
    // .ui后生成一个.h,里面有一个UI_MainWindow类,Ui::MainWindow继承于UI_MainWindow类
    // 提前声明 + 不include而在cpp才包含 + 使用非指针,是为了解耦合,修改ui文件时不需要重新编译incldue此类的文件。设计模式的思想
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

ui_mainwindow.h(ui的生成文件)

这个要在QtCreator中的过滤取勾 “隐藏生成的文件”,才可以看到

// ...

class Ui_MainWindow
{
    // ...
};

/**定义一个新类 Ui::MainWindow
 * Ui::MainWindow和MainWindow不是同一个类!!!
 * 前者继承于Ui_MainWindow,而后者继承与QMainWindow,后者包含前者的指针
 * 如果在 MainWindow.cpp 中 using namespace ui; 则可能会导致两者混淆
 */
namespace Ui {
    class MainWindow: public Ui_MainWindow {};
}

// ...

widget.cpp(窗口类的实现代码)

#include "mainwindow.h"
#include "ui_mainwindow.h"		// 这个.h是.ui文件生成出来的

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)	// 不是多重继承,如果是多重继承的话应该在头文件看。这里是列表初始化
{
    // ui = new Ui::MainWindow;	// 第二种写法 —— 不适用列表初始化
    ui->setupUi(this);
}

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

ProjectName.pro(工程文件)

代码(好像不支持尾注释,这就十分操蛋了)

# Qt包含的模块
QT       += core gui

# 大于4版本以上,则包含widget模块
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

# TARGET = ProjectName	# 编译时窗口的名字、和编译的exe文件的名字
# TEMPLATE = app		# 模板,为空则默认为应用程序模板,即app
CONFIG += c++11

# 如果代码使用了弃用的API,则可能导致编译失败 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文件(自动添加)
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

ui_mainwindow.h(生成文件,默认隐藏)

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

#ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_H

#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_MainWindow
{
public:
    QWidget *centralwidget;
    QPushButton *pushButton;
    QMenuBar *menubar;
    QStatusBar *statusbar;

/**
 * @brief 初始化Ui,这个公有方法会在窗口类的cpp构造函数中被调用
 * @return 无
 * @other 这个头文件均为内联函数,即没有对应的cpp文件只有头文件
 */
    void setupUi(QMainWindow *MainWindow)
    {
        if (MainWindow->objectName().isEmpty())
            MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
        MainWindow->resize(800, 600);
        centralwidget = new QWidget(MainWindow);
        centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
        pushButton = new QPushButton(centralwidget);
        pushButton->setObjectName(QString::fromUtf8("pushButton"));
        pushButton->setGeometry(QRect(360, 300, 341, 171));
        MainWindow->setCentralWidget(centralwidget);
        menubar = new QMenuBar(MainWindow);
        menubar->setObjectName(QString::fromUtf8("menubar"));
        menubar->setGeometry(QRect(0, 0, 800, 23));
        MainWindow->setMenuBar(menubar);
        statusbar = new QStatusBar(MainWindow);
        statusbar->setObjectName(QString::fromUtf8("statusbar"));
        MainWindow->setStatusBar(statusbar);

        retranslateUi(MainWindow);

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

    void retranslateUi(QMainWindow *MainWindow)
    {
        MainWindow->setWindowTitle(QCoreApplication::translate("MainWindow", "MainWindow", nullptr));
        pushButton->setText(QCoreApplication::translate("MainWindow", "PushButton", nullptr));
    } // retranslateUi

};

/**
 * 名称空间 - Ui
 * 在主窗口的头文件中:namespace Ui {class MainWindow;}
 * 即MainWindow在名称空间Ui中
 */
namespace Ui {
    class MainWindow: public Ui_MainWindow {};
}

QT_END_NAMESPACE

#endif // UI_MAINWINDOW_H

文件夹结构

build文件夹

用Qt进行构建后会在于工程文件夹同目录下生成一个名为build-ProjectName...的文件夹

该文件夹包含debug和release版本,里面有exe文件

可能会出现在QtCreator中能编译,但运行debug里的exe会报错:找不到xxx.dll文件(比如Qt5Cored.dll、Qt5Widgetsd.dll)

解决方法:因为没有配置环境变量,或者可以直接把那几个dll拷贝进exe所属目录底下,或者封装exe和dll文件

(dll所在位置:Qt安装路径\Tools\QtCreator\bin)