網(wǎng)站店鋪分布圖怎么做網(wǎng)絡(luò)營(yíng)銷專業(yè)是學(xué)什么的
Hello Qt 程序?qū)崿F(xiàn)
? 使用“按鈕”實(shí)現(xiàn)
純代碼方式實(shí)現(xiàn):
// Widget構(gòu)造函數(shù)的實(shí)現(xiàn)
Widget::Widget(QWidget *parent): QWidget(parent) // 使用父類構(gòu)造函數(shù)初始化QWidget,傳入父窗口指針, ui(new Ui::Widget) // 創(chuàng)建Ui::Widget類的實(shí)例,并用new動(dòng)態(tài)分配內(nèi)存
{// 調(diào)用ui的setupUi函數(shù)來(lái)初始化界面,傳入this指針,即將當(dāng)前Widget實(shí)例與設(shè)計(jì)的UI綁定ui->setupUi(this);// 創(chuàng)建一個(gè)QPushButton對(duì)象指針btnQPushButton *btn = new QPushButton;// 設(shè)置按鈕的文本為"Hello_Qt"btn->setText("Hello_Qt");// 設(shè)置按鈕的父窗口為當(dāng)前Widget,這樣按鈕會(huì)自動(dòng)被管理(包括銷毀)btn->setParent(this);
}// Widget析構(gòu)函數(shù)的實(shí)現(xiàn)
Widget::~Widget()
{// 釋放ui指針?biāo)赶虻膬?nèi)存,防止內(nèi)存泄漏delete ui;
}
?代碼結(jié)果:
可視化操作實(shí)現(xiàn):
(1)雙擊:" widget.ui " ?件;
(2)拖拽控件? ui 界?窗?并修改內(nèi)容;
(3)構(gòu)建并運(yùn)?,效果如下所?:
?
? 使用?"標(biāo)簽" 實(shí)現(xiàn)
純代碼方式實(shí)現(xiàn):
#include "widget.h" // 包含自定義Widget類的頭文件
#include "ui_widget.h" // 包含由Qt Designer生成的用戶界面類頭文件
#include <QLabel> // 包含QLabel控件的頭文件,用于顯示文本
#include <QFont> // 包含QFont類,用于設(shè)置字體樣式// Widget類的構(gòu)造函數(shù)
Widget::Widget(QWidget *parent): QWidget(parent) // 調(diào)用基類QWidget的構(gòu)造函數(shù),傳入父窗口指針, ui(new Ui::Widget) // 使用new動(dòng)態(tài)創(chuàng)建Ui::Widget實(shí)例
{// 初始化由Qt Designer設(shè)計(jì)的界面ui->setupUi(this);// 創(chuàng)建一個(gè)新的QLabel對(duì)象,并將其父窗口設(shè)為當(dāng)前WidgetQLabel *lab = new QLabel(this);// 設(shè)置QLabel的顯示文本為"Hello Qt"lab->setText("Hello Qt");// 設(shè)置窗口固定大小為800x600像素setFixedSize(800, 600);// 創(chuàng)建QFont對(duì)象,設(shè)置字體為"華文行楷",字號(hào)為64QFont font("華文行楷", 64);// 將創(chuàng)建的字體應(yīng)用到QLabel上lab->setFont(font);// 移動(dòng)QLabel的位置到屏幕上的(0, 300)lab->move(0, 300);// 設(shè)置QLabel的文字顏色為藍(lán)色lab->setStyleSheet("color:blue");
}// Widget類的析構(gòu)函數(shù)
Widget::~Widget()
{// 清理由new分配的ui對(duì)象,防止內(nèi)存泄漏delete ui;
}
代碼結(jié)果:
可視化操作實(shí)現(xiàn):
(1)雙擊:" widget.ui " ?件;
(2)拖拽 "標(biāo)簽" ? UI 設(shè)計(jì)界?中,并雙擊修改標(biāo)簽內(nèi)容;
(3)實(shí)現(xiàn)效果如下圖所?:
項(xiàng)目文件解析
????????在我們創(chuàng)建完一個(gè)項(xiàng)目后,Qt Creator 會(huì)默認(rèn)給我們生成以下文件:
? 解釋 .pro?
# Qt項(xiàng)目配置文件 (.pro) 示例# 添加必需的Qt模塊:core和gui。core模塊包含基礎(chǔ)運(yùn)行時(shí)功能,而gui模塊用于構(gòu)建圖形用戶界面。
QT += core gui# 如果當(dāng)前使用的Qt版本主版本號(hào)大于4,則額外添加widgets模塊,因?yàn)閺腝t5開始,widgets被分離出來(lái)作為一個(gè)獨(dú)立模塊。
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets# 配置項(xiàng)目以使用C++11標(biāo)準(zhǔn)。這對(duì)于利用現(xiàn)代C++特性如auto、lambda表達(dá)式等是必要的。
CONFIG += c++11# 定義宏QT_DEPRECATED_WARNINGS,使得編譯器在遇到Qt中已標(biāo)記為過(guò)時(shí)的功能時(shí)發(fā)出警告。
# 這有助于開發(fā)者及時(shí)遷移代碼,避免使用即將不支持的API。
DEFINES += QT_DEPRECATED_WARNINGS# 注釋掉的行展示了如何禁止使用指定版本之前的所有過(guò)時(shí)API。
# 解除注釋并設(shè)置期望的版本(如QT_DISABLE_DEPRECATED_BEFORE=0x060000禁用Qt6.0.0前的過(guò)時(shí)API),
# 可強(qiáng)制編譯失敗而不是警告,確保代碼完全不含舊API。
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # 禁用所有在Qt 6.0.0之前廢棄的API# 指定源文件,項(xiàng)目將從這些文件編譯生成可執(zhí)行代碼。
SOURCES += \main.cpp \widget.cpp# 指定頭文件,這些是源文件中可能引用的聲明文件。
HEADERS += \widget.h# 指定UI表單文件,這些是通過(guò)Qt Designer設(shè)計(jì)的界面文件,將被編譯為C++代碼。
FORMS += \widget.ui# 部署規(guī)則設(shè)定:
# - 對(duì)于QNX系統(tǒng),目標(biāo)路徑設(shè)置為/tmp/${TARGET}/bin
# - 對(duì)于其他Unix系統(tǒng)(非Android),目標(biāo)路徑設(shè)置為/opt/${TARGET}/bin
# 如果target.path被設(shè)置了(即不為空),那么會(huì)自動(dòng)添加一個(gè)安裝步驟(INSTALLS += target)來(lái)安裝生成的可執(zhí)行文件到指定路徑。
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
?.pro ?件的寫法如下:
1. 注釋:從 "#" 開始,到這??結(jié)束。
2. QT += core gui // Qt 包含的模塊 Qt5 包含的模塊如下圖所?:
3. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 這條語(yǔ)句的含義是,如果QT_MAJOR_VERSION ?于 4 也就是當(dāng)前使?的 Qt5 及更?版本) 需要增加 widgets 模塊。如果項(xiàng)?僅需?持 Qt5 , 也可以直接添加 "QT += widgets" ?句。不過(guò)為了保持代碼兼容 ,最好還是按照 QtCreator ?成的語(yǔ)句編寫。
4. 指定?成的應(yīng)?程序名:TARGET = QtDemo
5. TEMPLATE = app //模板。告訴 qmake 為這個(gè)應(yīng)?程序?成哪種 makefile。下?是可供選擇的模板:
? app:建??個(gè)應(yīng)?程序的 makefile。這是默認(rèn)值,所以如果模板沒(méi)有被指定,這個(gè)將被使?。
? lib :建??個(gè)庫(kù)的 makefile。
? vcapp:建??個(gè)應(yīng)?程序的 VisualStudio 項(xiàng)??件。
? vclib: 建??個(gè)庫(kù)的 VisualStudio 項(xiàng)??件。
? subdirs:這是?個(gè)特殊的模板,它可以創(chuàng)建?個(gè)能夠進(jìn)?特定?錄的 makefile 并且為它調(diào)?make 的 makefile。
6. ?程中包含的源?件:SOURCES += main.cpp/widget.cpp
7. ?程中包含的頭?件:HEADERS += widget.h
8. ?程中包含的資源?件:RESOURCES += painter.qrc
9. ?程中包含的 "ui" 設(shè)計(jì)?件:FORMS += widget.ui
10. 配置信息:CONFIG += c++11 (使? c++11 的特性) CONFIG ?來(lái)告訴 qmake 關(guān)于應(yīng)?程序的配置信息。
? 解釋widget.h
// widget.h 文件頭部使用預(yù)處理器指令防止多次包含
#ifndef WIDGET_H
#define WIDGET_H// 包含基類 QWidget 的頭文件,以便繼承
#include <QWidget>// 使用QT_BEGIN_NAMESPACE和QT_END_NAMESPACE包裹Ui命名空間的聲明,
// 以符合Qt的編碼規(guī)范,避免命名沖突。
QT_BEGIN_NAMESPACE
namespace Ui {// 前向聲明Ui::Widget類,該類由uic自動(dòng)生成并用于界面管理class Widget;
}
QT_END_NAMESPACE// 類Widget的聲明,它公有繼承自QWidget
class Widget : public QWidget
{// Q_OBJECT 宏是必須的,用于Qt的信號(hào)與槽機(jī)制以及國(guó)際化支持Q_OBJECTpublic:// 構(gòu)造函數(shù),接受一個(gè)指向父組件的指針,默認(rèn)為nullptrexplicit Widget(QWidget *parent = nullptr);// 析構(gòu)函數(shù),清理資源~Widget();private:// 私有成員變量,指向由Qt設(shè)計(jì)師生成的界面類實(shí)例Ui::Widget *ui; // 實(shí)例化Ui::Widget用于界面控制
};// 結(jié)束條件編譯,確保WIDGET_H只被定義一次
#endif // WIDGET_H
????????在Qt中,如果要使?信號(hào)與槽(signal 和 slot)的機(jī)制 就必須加? Q_OBJECT 宏;
????????Ui::Widget *ui; 這個(gè)指針是?前?聲明的 namespace Ui ?的 Widget 類定義的,所以指針 ui 是指向可視化設(shè)計(jì)的界?,后?要訪問(wèn)界?上的組件,都需要通過(guò)這個(gè)指針 ui 去訪問(wèn)。
? 解釋 main.cpp
// 包含自定義窗口部件類(Widget)的實(shí)現(xiàn)文件
#include "widget.h"// 引入QApplication類,用于管理整個(gè)GUI應(yīng)用程序的控制流程
#include <QApplication>// 應(yīng)用程序的主函數(shù)
int main(int argc, char *argv[])
{// 創(chuàng)建QApplication對(duì)象,argc和argv是從命令行傳入的參數(shù),// 這一行是Qt GUI應(yīng)用的起點(diǎn),管理事件循環(huán)和提供系統(tǒng)級(jí)別的功能QApplication a(argc, argv);// 實(shí)例化自定義窗口部件Widget類Widget w;// 調(diào)用窗口部件的show()方法,使窗口在屏幕上顯示出來(lái)w.show();// 啟動(dòng)Qt的事件循環(huán),a.exec()會(huì)一直運(yùn)行直到事件循環(huán)結(jié)束,// 通常當(dāng)所有窗口關(guān)閉時(shí)事件循環(huán)結(jié)束,然后返回 exitCode 給操作系統(tǒng)return a.exec();
}
解釋:
1. Qt 系統(tǒng)提供的標(biāo)準(zhǔn)類名 聲明頭?件沒(méi)有 .h 后綴;
2. Qt ?個(gè)類對(duì)應(yīng)?個(gè)頭?件,類名 就是 頭?件名;
3. QApplication 為應(yīng)?程序類;QApplication a;(a為應(yīng)?程序?qū)ο?#xff0c;有且僅有?個(gè)。)
? QApplication 管理圖形??界?應(yīng)?程序的控制流和主要設(shè)置。
? QApplication 是 Qt 的整個(gè)后臺(tái)管理的命脈。它包含主事件循環(huán),在其中來(lái)?窗?系統(tǒng)和其它資源的所有事件處理和調(diào)度。它也處理應(yīng)?程序的初始化和結(jié)束,并且提供對(duì)話管理。
? 對(duì)于任何?個(gè)使? Qt 的圖形??界?應(yīng)?程序,都正好存在?個(gè) QApplication 對(duì)象,?不論這個(gè)應(yīng)?程序在同?時(shí)間內(nèi)是不是有 0、1、2 或更多個(gè)窗?。
4. myWidget w; //實(shí)例化窗?對(duì)象
5. w.show(); //調(diào)?show函數(shù)顯?窗?
6. a.exec() :程序進(jìn)?消息循環(huán),等待對(duì)??輸?進(jìn)?響應(yīng)。這? main()把控制權(quán)轉(zhuǎn)交給Qt,Qt 完成事件處理?作,當(dāng)應(yīng)?程序退出的時(shí)候 exec() 的值就會(huì)返回。在 exec() 中,Qt 接受并處理??和系統(tǒng)的事件并且把它們傳遞給適當(dāng)?shù)拇?部件。?
? 解釋widget.cpp
????????widget.cpp ?件是類 Widget 的實(shí)現(xiàn)代碼,所有在窗體上要實(shí)現(xiàn)的功能添加在此?件中;?
// 包含自定義窗口部件類的頭文件
#include "widget.h" // 包含由Qt Designer生成的用戶界面類頭文件,用于界面布局和控件
#include "ui_widget.h"// Widget類構(gòu)造函數(shù)
Widget::Widget(QWidget *parent): QWidget(parent) // 使用基類QWidget的構(gòu)造函數(shù)初始化,傳入父窗口指針, ui(new Ui::Widget) // 創(chuàng)建Ui::Widget類的實(shí)例,并用new動(dòng)態(tài)分配內(nèi)存
{// 調(diào)用ui->setupUi(this)來(lái)初始化界面,this指針指向當(dāng)前Widget實(shí)例,// 這一步會(huì)根據(jù).ui文件設(shè)置窗口的布局和控件ui->setupUi(this);
}// Widget類析構(gòu)函數(shù)
Widget::~Widget()
{// 當(dāng)Widget實(shí)例被銷毀時(shí),釋放之前動(dòng)態(tài)分配的ui對(duì)象的內(nèi)存delete ui;
}
? 解釋widget.ui
????????widget.ui 是窗體界?定義?件,是?個(gè) XML ?件,定義了窗?上的所有組件的屬性設(shè)置、布局,及其信號(hào)與槽函數(shù)的關(guān)聯(lián)等。? UI 設(shè)計(jì)器可視化設(shè)計(jì)的界?都由 Qt ?動(dòng)解析,并以 XML ?件的形式保存下來(lái)。在設(shè)計(jì)界?時(shí),只需在 UI 設(shè)計(jì)器?進(jìn)?可視化設(shè)計(jì)即可,?不?管 widget.ui ?件是怎么?成的。?
<!-- XML聲明部分,定義了文檔的版本為1.0,字符編碼為UTF-8 -->
<?xml version="1.0" encoding="UTF-8"?><!-- 開始定義Qt用戶界面文件,版本號(hào)為4.0 -->
<ui version="4.0"><!-- 定義用戶界面的主類名為Widget --><class>Widget</class><!-- 實(shí)際的窗口部件配置開始,這是一個(gè)QWidget類型的窗口部件 --><widget class="QWidget" name="Widget"><!-- 設(shè)置窗口部件的初始幾何屬性 --><property name="geometry"><!-- 使用矩形(rect)來(lái)具體定義位置和大小 --><rect><x>0</x> <!-- X軸坐標(biāo)起始于0 --><y>0</y> <!-- Y軸坐標(biāo)起始于0 --><width>800</width> <!-- 窗口寬度為800像素 --><height>600</height> <!-- 窗口高度為600像素 --></rect></property><!-- 設(shè)置窗口的標(biāo)題 --><property name="windowTitle"><string>Widget</string> <!-- 窗口標(biāo)題為"Widget" --></property></widget> <!-- QWidget配置結(jié)束 --><!-- 資源部分,目前沒(méi)有定義任何額外資源 --><resources/><!-- 連接部分,目前沒(méi)有定義任何信號(hào)與槽的連接 --><connections/></ui> <!-- 用戶界面定義結(jié)束 -->
Qt 編程注意事項(xiàng)
? Qt 中的命名規(guī)范
- 類名:?字??寫,單詞和單詞之間?字??寫;
- 函數(shù)名及變量名:?字??寫,單詞和單詞之間?字??寫;
? Qt Creator 中的快捷鍵
- 注釋:ctrl + /
- 運(yùn)?:ctrl + R
- 編譯:ctrl + B
- 字體縮放:ctrl + ?標(biāo)滑輪
- 查找:ctrl + F
- 整?移動(dòng):ctrl + shift + ?/?
- 幫助?檔:F1
- ?動(dòng)對(duì)?:ctrl + i;
- 同名之間的 .h 和 .cpp 的切換:F4
- ?成函數(shù)聲明的對(duì)應(yīng)定義: alt + enter?
??使用幫助文檔
打開幫助?檔有三種?式. 實(shí)際編程中使?哪種都可以.
????????1、光標(biāo)放到要查詢的類名/?法名上, 直接按 F1。
????????2、Qt Creator 左側(cè)邊欄中直接??標(biāo)單擊 "幫助" 按鈕:
????????3、找到 Qt Creator 的安裝路徑,在 "bin" ?件夾下找到 assistant.exe,雙擊打開;
? 認(rèn)識(shí)對(duì)象模型(對(duì)象樹)
????????在 Qt 中創(chuàng)建很多對(duì)象的時(shí)候會(huì)提供?個(gè) Parent 對(duì)象指針,下?來(lái)解釋這個(gè) parent 到底是?什么的。
QObject 是以對(duì)象樹的形式組織起來(lái)的。
- 當(dāng)創(chuàng)建?個(gè) QObject 對(duì)象時(shí),會(huì)看到 QObject 的構(gòu)造函數(shù)接收?個(gè) QObject 指針作為參數(shù),這 個(gè)參數(shù)就是 parent,也就是?對(duì)象指針。
- 這相當(dāng)于,在創(chuàng)建 QObject 對(duì)象時(shí),可以提供?個(gè)其?對(duì)象,我們創(chuàng)建的這個(gè) QObject 對(duì)象 會(huì)?動(dòng)添加到其?對(duì)象的 children() 列表。
- 當(dāng)?對(duì)象析構(gòu)的時(shí)候,這個(gè)列表中的所有對(duì)象也會(huì)被析構(gòu)。(注意,這?的?對(duì)象并不是繼承意義上的?類!)
????????這種機(jī)制在 GUI 程序設(shè)計(jì)中相當(dāng)有?。例如,?個(gè)按鈕有?個(gè) QShortcut(快捷鍵)對(duì)象作為其?對(duì)象。當(dāng)刪除按鈕的時(shí)候,這個(gè)快捷鍵理應(yīng)被刪除。這是合理的。
QWidget 是能夠在屏幕上顯?的?切組件的?類。
- QWidget 繼承? QObject ,因此也繼承了這種對(duì)象樹關(guān)系。?個(gè)孩??動(dòng)地成為?組件的?個(gè)?組件。因此,它會(huì)顯?在?組件的坐標(biāo)系統(tǒng)中,被?組件的邊界剪裁。例如,當(dāng)??關(guān)閉?個(gè)對(duì)話框的時(shí)候,應(yīng)?程序?qū)⑵鋭h除,那么,我們希望屬于這個(gè)對(duì)話框的按鈕、圖標(biāo)等應(yīng)該?起被刪除。事實(shí)就是如此,因?yàn)檫@些都是對(duì)話框的?組件。
- 當(dāng)然,我們也可以??刪除?對(duì)象,它們會(huì)?動(dòng)從其?對(duì)象列表中刪除。?如,當(dāng)我們刪除了?個(gè)?具欄時(shí),其所在的主窗?會(huì)?動(dòng)將該?具欄從其?對(duì)象列表中刪除,并且?動(dòng)調(diào)整屏幕顯?。
Qt 引?對(duì)象樹的概念,在?定程度上解決了內(nèi)存問(wèn)題。
- 當(dāng)?個(gè) QObject 對(duì)象在堆上創(chuàng)建的時(shí)候,Qt 會(huì)同時(shí)為其創(chuàng)建?個(gè)對(duì)象樹。不過(guò),對(duì)象樹中對(duì)象的順序是沒(méi)有定義的。這意味著,銷毀這些對(duì)象的順序也是未定義的。
- 任何對(duì)象樹中的 QObject 對(duì)象 delete 的時(shí)候,如果這個(gè)對(duì)象有 parent,則?動(dòng)將其從 parent 的children() 列表中刪除;如果有孩?,則?動(dòng) delete 每?個(gè)孩?。Qt 保證沒(méi)有 QObject 會(huì)被delete 兩次,這是由析構(gòu)順序決定的。
????????如果 QObject 在棧上創(chuàng)建,Qt 保持同樣的?為。正常情況下,這也不會(huì)發(fā)?什么問(wèn)題。來(lái)看下?的代碼?段:
????????作為?組件的 window 和作為?組件的 quit 都是 QObject 的?類(事實(shí)上,它們都是QWidget的?類,?QWidget 是 QObject 的?類)。這段代碼是正確的,quit 的析構(gòu)函數(shù)不會(huì)被調(diào)?兩次,因?yàn)闃?biāo)準(zhǔn) C++ 要求,局部對(duì)象的析構(gòu)順序應(yīng)該按照其創(chuàng)建順序的相反過(guò)程。因此,這段代碼在超出作?域時(shí),會(huì)先調(diào)? quit 的析構(gòu)函數(shù),將其從?對(duì)象 window 的?對(duì)象列表中刪除,然后才會(huì)再調(diào)?window 的析構(gòu)函數(shù)。
????????但是,如果我們使?下?的代碼:
????????情況?有所不同,析構(gòu)順序就有了問(wèn)題。我們看到,在上?的代碼中,作為?對(duì)象的 window 會(huì)?先被析構(gòu),因?yàn)樗亲詈?個(gè)創(chuàng)建的對(duì)象。在析構(gòu)過(guò)程中,它會(huì)調(diào)??對(duì)象列表中每?個(gè)對(duì)象的析構(gòu)函數(shù),也就是說(shuō), quit 此時(shí)就被析構(gòu)了。然后,代碼繼續(xù)執(zhí)?,在 window 析構(gòu)之后,quit 也會(huì)被析構(gòu),因?yàn)?quit 也是?個(gè)局部變量,在超出作?域的時(shí)候當(dāng)然也需要析構(gòu)。但是,這時(shí)候已經(jīng)是第?次調(diào)? quit 的析構(gòu)函數(shù)了,C++ 不允許調(diào)?兩次析構(gòu)函數(shù),因此,程序崩潰了。
????????由此我們看到,Qt 的對(duì)象樹機(jī)制雖然在?定程度上解決了內(nèi)存問(wèn)題,但是也引?了?些值得注意的事情。這些細(xì)節(jié)在今后的開發(fā)過(guò)程中很可能時(shí)不時(shí)跳出來(lái)煩擾?下,所以,我們最好從開始就養(yǎng)成良好習(xí)慣。
總結(jié):在 Qt 中,盡量在構(gòu)造的時(shí)候就指定 parent 對(duì)象,并且?膽在堆上創(chuàng)建。
Qt對(duì)象樹如圖:
? Qt 窗口坐標(biāo)體系
????????坐標(biāo)體系:以左上?為原點(diǎn)(0,0),X向右增加,Y向下增加。
????????對(duì)于嵌套窗?,其坐標(biāo)是相對(duì)于?窗?來(lái)說(shuō)的。
?例:使?Qt中的坐標(biāo)系設(shè)置控件的位置;
?代碼結(jié)果: