深入理解Qt 初始項(xiàng)目代碼
當(dāng)創(chuàng)建完項(xiàng)目時(shí)看到這樣的界面:

本文將聚焦與項(xiàng)目創(chuàng)建后的這5個(gè)文件的解析,這5個(gè)文件分別為: test250225, mywidget.h, main.cpp, mywidget.cpp, mywidget.ui。
現(xiàn)在開(kāi)始逐個(gè)解析
1. main.cpp內(nèi)容解析
#include "mywidget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyWidget w;
w.show();
return a.exec();
}該函數(shù)中的QApplication a這是編寫(xiě)Qt圖形化界面一定需要的對(duì)象,它的作用為:
- 應(yīng)用程序的初始化
- 事件循環(huán)管理
- 窗口管理
- GUI相關(guān)功能
- 全局資源管理
在 Qt Widgets 應(yīng)用程序中,通常必須創(chuàng)建QApplication對(duì)象,否則 GUI 組件無(wú)法正常工作。
繼續(xù)往下看,MyWidget是創(chuàng)建項(xiàng)目時(shí),填寫(xiě)的類(lèi)名。w.show()的作用是創(chuàng)建一個(gè)控件對(duì)象,并顯示出來(lái),同時(shí)你還可以用.hide()讓控件隱藏,注意Wight的父類(lèi)是QWight,Wight中的方法大部分都是繼承至父類(lèi)。
然后我們來(lái)看a.exec()這個(gè)有沒(méi)有很熟悉,如果你學(xué)過(guò)Linux,在Linux中有一個(gè)進(jìn)程程序替換的函數(shù),確切來(lái)說(shuō)是6個(gè)函數(shù),他們是一個(gè)系列,可以把可執(zhí)行文件中的代碼和數(shù)據(jù)替換到當(dāng)前進(jìn)程中。
是不是覺(jué)得他們有什么關(guān)系呢?
完全沒(méi)有如何關(guān)系?。?!
只是名字一樣而已,就像家豪這個(gè)名字,可能你遇到過(guò)幾個(gè)家豪,只是名字一樣而已。
在計(jì)算機(jī)的世界,這種情況并不少見(jiàn),你還能想到其他例子嗎?
你肯定想到了計(jì)算機(jī)中的棧和堆了吧,有數(shù)據(jù)結(jié)構(gòu)中的棧和堆,還有操作系統(tǒng)中的棧和堆甚至還有JVM中的棧和堆,這3種棧和堆都有不同的概念,但是他們的名字相同。
主函數(shù)介紹完了,我們開(kāi)始介紹其他文件。
2. mywidget.h內(nèi)容解析
#ifndef MYWIDGET_H
#define MYWIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class MyWidget; }
QT_END_NAMESPACE
class MyWidget : public QWidget//繼承父類(lèi)
{
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這個(gè)類(lèi)。
在這里我們主要還是關(guān)注這個(gè)類(lèi),這個(gè)類(lèi)就是我們創(chuàng)建項(xiàng)目時(shí)所命名的,可以看到它確實(shí)繼承至QWight我們可以看到類(lèi)中存在著一個(gè)宏,Q_OBJECT是Qt中一個(gè)內(nèi)置的宏,宏本質(zhì)上就是文本替換,其實(shí)它會(huì)替換為一大堆代碼。
跳轉(zhuǎn)過(guò)去看看:

看不懂。。。
Qt中有一個(gè)非常核心的機(jī)制,“信號(hào)和槽”,如果某個(gè)類(lèi)想要使用"信號(hào)和槽"就需要引入這個(gè)宏。
在往下看,就是構(gòu)造函數(shù)和析構(gòu)函數(shù),析構(gòu)函數(shù)沒(méi)什么好講的,我們看到構(gòu)造函數(shù),構(gòu)造函數(shù)的形參是一個(gè)QWidget類(lèi)型的缺省。
這里其實(shí)存在著一個(gè)Qt中引入的對(duì)象樹(shù)機(jī)制(目前不解釋?zhuān)?br />創(chuàng)建的Qt對(duì)象可把這個(gè)對(duì)象給掛到對(duì)象樹(shù)上,往樹(shù)上掛的時(shí)候就需要指定父節(jié)點(diǎn)(這里的樹(shù)是n叉樹(shù))
3. mywidget.cpp內(nèi)容解析
#include "mywidget.h"http://創(chuàng)建項(xiàng)目生成的頭文件
#include "ui_mywidget.h"http://form file被qmake生成的頭文件
MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::MyWidget)
{
ui->setupUi(this);//把form file生成的界面和當(dāng)前widget關(guān)聯(lián)起來(lái)
}
MyWidget::~MyWidget()
{
delete ui;
}

4. form file內(nèi)容解析
雙擊文件mywidget.ui文件

會(huì)進(jìn)入設(shè)計(jì)界面

左邊是Qt內(nèi)置的1控件,可以直接拖拽到右邊的程序窗口,沒(méi)錯(cuò)我們還可以這樣創(chuàng)建出具體的界面。每個(gè)控件都有很多屬性,我們可以自行設(shè)計(jì)控件的屬性
點(diǎn)擊左側(cè)欄的編輯按鈕,此時(shí)顯示的內(nèi)容,就是.ui文的本體了

<?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>
看到這個(gè)格式有沒(méi)有一點(diǎn)熟悉,有點(diǎn)像html的標(biāo)簽?zāi)J?,但是呢這個(gè)格式被稱(chēng)為xml格式
xml這里的標(biāo)簽是可以程序員自定義的,有點(diǎn)類(lèi)似于網(wǎng)絡(luò)中的自定義應(yīng)用層協(xié)議。而html的標(biāo)簽是由標(biāo)準(zhǔn)委員會(huì)約定的,所有的瀏覽器也是按照約定來(lái)解釋的
Qt中使用xml文件就是描述程序的界面是啥樣的,再進(jìn)一步的qmake文件會(huì)調(diào)用相關(guān)的工具依據(jù)這個(gè)xml文件生成一些C++代碼,從而把完整的界面構(gòu)造出來(lái)。
5. .pro內(nèi)容解析
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
現(xiàn)在看到.pro Qt的工程文件,也是qmake工具構(gòu)建的重要依據(jù),注意:.pro類(lèi)似Linux中的makefile文件是一個(gè)自動(dòng)化構(gòu)建工具
直接看總結(jié)版:
| 部分 | 作用 |
|---|---|
| QT += core gui | 添加 QtCore 和 QtGui 模塊(基礎(chǔ)功能和 GUI 支持)。 |
| QT += widgets | Qt 5+ 需要額外添加 QtWidgets 以使用 QWidget。 |
| CONFIG += c++11 | 啟用 C++11 語(yǔ)法支持。 |
| DEFINES += QT_DEPRECATED_WARNINGS | 啟用 Qt 過(guò)時(shí) API 的警告。 |
| SOURCES += main.cpp mywidget.cpp | 指定 .cpp 源文件。 |
| HEADERS += mywidget.h | 指定 .h 頭文件。 |
| FORMS += mywidget.ui | 指定 Qt Designer 的 .ui 文件。 |
| target.path | 設(shè)置不同平臺(tái)的安裝路徑。 |
![]() |
紅框中的內(nèi)容是描述當(dāng)前項(xiàng)目中,參與構(gòu)建的文件都有什么,這地方不需要手動(dòng)修改,qt Creator會(huì)幫我們自動(dòng)維護(hù)好。
上面我們看到的都是源代碼,其實(shí)在編譯運(yùn)行中還會(huì)產(chǎn)生一些中間文件。
打開(kāi)文件自愿管理器,看看項(xiàng)目對(duì)應(yīng)的目錄是什么樣子~


在運(yùn)行一次程序后,就會(huì)在項(xiàng)目并列的地方多出來(lái)一個(gè)buildxxx目錄
這個(gè)目錄是用來(lái)存儲(chǔ)運(yùn)行過(guò)程中的臨時(shí)文件的。

打開(kāi)目錄,看到了一個(gè)makefile文件,看來(lái)編譯Qt程序還是會(huì)用到makefile文件啊,由qmake自動(dòng)生成。
然后我們,再看到ui_mywidget.h文件,該文件是根據(jù)前面的xml文件自動(dòng)生成的,打開(kāi)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. 總結(jié)
總結(jié)來(lái)說(shuō),Qt 初始代碼的結(jié)構(gòu)清晰且模塊化,充分體現(xiàn)了 Qt 框架的設(shè)計(jì)哲學(xué)。從 QApplication 的初始化到 QWidget 的父子管理機(jī)制,再到 .pro 文件的配置,每個(gè)部分都在確保應(yīng)用的穩(wěn)定性和可擴(kuò)展性。理解這些基礎(chǔ)代碼,不僅有助于掌握 Qt 的事件循環(huán)、窗口管理和資源組織方式,還能為后續(xù)的開(kāi)發(fā)打下堅(jiān)實(shí)的基礎(chǔ)。希望這篇解析能幫助你更高效地入門(mén) Qt,并為更復(fù)雜的應(yīng)用開(kāi)發(fā)做好準(zhǔn)備。
到此這篇關(guān)于深入理解Qt 初始項(xiàng)目代碼的文章就介紹到這了,更多相關(guān)Qt 初始項(xiàng)目代碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++使用boost::lexical_cast進(jìn)行數(shù)值轉(zhuǎn)換
這篇文章介紹了C++使用boost::lexical_cast進(jìn)行數(shù)值轉(zhuǎn)換的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06
C++ 基于BFS算法的走迷宮自動(dòng)尋路的實(shí)現(xiàn)
這篇文章主要為大家介紹了C++ 基于BFS算法實(shí)現(xiàn)走迷宮自動(dòng)尋路,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11
C語(yǔ)言實(shí)現(xiàn)統(tǒng)計(jì)字符串單詞數(shù)
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)統(tǒng)計(jì)字符串單詞數(shù),代碼非常的簡(jiǎn)潔,有需要的小伙伴快來(lái)參考下。2015-03-03
C++中圖片類(lèi)型的識(shí)別與轉(zhuǎn)換詳解方法
本文簡(jiǎn)單的介紹一下C++語(yǔ)言中如何識(shí)別圖片文件的類(lèi)型,以及各圖片類(lèi)型之間的轉(zhuǎn)換方法,并提供相關(guān)的源碼供大家參考,感興趣的朋友快來(lái)看看吧2021-11-11
使用MySQL編程實(shí)現(xiàn)C語(yǔ)言功能強(qiáng)大化步驟示例
這篇文章主要為大家介紹了使用MySQL編程實(shí)現(xiàn)C語(yǔ)言功能強(qiáng)大化步驟示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05


