qt ui界面加入qsplitter_UI 文件设计与运行机制
上一篇通過一個 “Hello World” 實例,演示了在 Qt Creator 里創建應用程序、設計窗體界面、編譯和運行程序的基本過程。這一篇將介紹可視化設計的 UI 界面文件的原理和運行機制。
本篇目錄:
?? 1. 項目文件組成
?? 2. 項目管理文件
?? 3. 界面文件
?? 4. 主函數文件
?? 5. 窗體相關的文件
?1. 項目文件組成?
在 Qt Creator 中新建一個 Widget Application 項目,選擇 QWidget 作為窗體基類,并選中 “創建界面” 復選框。
選擇基類界面
創建后的項目文件目錄樹以及各文件說明如下圖所示。
項目文件的目錄樹
說明:在 C++ 里,任何窗體或界面組件都是用類封裝的,一般情況下,一個類包含一個頭文件 (.h) 和一個源程序文件 (.cpp)。
?2. 項目管理文件?
項目管理文件 (UImechanism.pro) 用于記錄項目的一些設置,以及項目包含文件的組織管理,其內容如下:(可以左右滑動以查看完整代碼,下同)
#-------------------------------------------------## Project created by QtCreator 2019-03-03T14:41:29##-------------------------------------------------QT???????+=?core?gui # 在項目中加入用于?GUI?設計的?core?gui?模塊greaterThan(QT_MAJOR_VERSION, 4): QT += widgets # 當 Qt 主版本大于 4 時,才加入 widgets 模塊TARGET?=?UImechanism # 生成的目標可執行文件的名稱,即?UImechanism.exeTEMPLATE = app # 項目使用的模板是 app,是一般的應用程序# The following define makes your compiler emit warnings if you use# any feature of Qt which has been marked as 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 you use 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.0CONFIG += c++11SOURCES += \ main.cpp \ widget.cppHEADERS += \ widget.hFORMS += \ widget.ui# Default rules for deployment.qnx: target.path = /tmp/$${TARGET}/binelse: unix:!android: target.path = /opt/$${TARGET}/bin!isEmpty(target.path): INSTALLS += targetQt 類庫以模塊的形式組織各種功能的類,根據項目涉及的功能需求,在項目中添加適當的類庫模塊支持。例如,如果項目中使用到了涉及數據庫操作的類就需要用到 sql 模塊,在 .pro 文件中需要增加如下一行:
Qt += sql后面的 SOURCES, HEADERS, FORMS 記錄了項目中包含的源程序文件、頭文件和窗體文件(.ui 文件)的名稱。這些文件列表是 Qt Creator 自動添加到項目管理文件里面的,用戶不需要手動修改。當添加一個文件到項目,或從項目里刪除一個文件時,項目管理文件里的條目會自動修改。
?3. 界面文件?
雙擊項目文件目錄樹中的窗體界面文件 (widget.ui),打開集成在 Qt Creator 中的 UI 設計器 (Qt Designer),其功能區域如下圖所示。
集成在 Qt Creator 中的 UI 設計器
將一個 Label 組件和一個 Push Button 組件拖放到設計的窗體上面,調整好位置。設置 Label 組件的 ”text“ 屬性為 “Hello, World”,“font“ -> ”點大小” 屬性為 20;設置 Push Button 組件的 ”text“ 屬性為 “關閉”。
窗體設計界面
選中窗體上的 Label 組件,屬性編輯器的內容如下:
界面組件 Label 的屬性編輯器
(屬性的多個分組表示了類的繼承關系,圖中 QLabel 的繼承關系是 QObject→QWidget→QFrame→QLabel)
選中窗體上的 Push Button 組件,屬性編輯器的內容如下:
界面組件 Push Botton 的屬性編輯器
編輯完兩個組件的屬性之后,再為 pushButton 按鈕添加一個功能:單擊此按鈕時,關閉窗口,退出程序。使用 ”信號與槽“ 編輯器完成這個功能,步驟如下:
單擊 ”信號與槽“ 編輯器左上角的 “+” 按鈕;
在出現的條目中,
選擇
選擇
選擇
選擇
信號與槽編輯器中設計信號與槽的關聯
對項目進行編譯和運行,可以出現如下圖所示的窗口,單擊 “關閉” 按鈕可以關閉程序。
運行結果
?4. 主函數文件?
主程序入口文件 main.cpp 是實現 main() 函數的文件,它的主要功能是創建應用程序,創建窗口,顯示窗口,并運行應用程序,開始應用程序的消息循環和事件處理,內容如下:
#include "widget.h"#include int main(int argc, char *argv[]){ QApplication a(argc, argv); // 定義并創建應用程序 Widget w; // 定義并創建窗口 w.show(); // 顯示窗口 return a.exec(); // 應用程序運行}?5. 窗體相關的文件?
對項目進行編譯和運行后,在項目的目錄下自動生成一個 ui_widget.h 文件,其中包含一個名稱是 Ui_Widget 的類,它是根據窗體上的組件及其屬性、信號與槽的關聯等自動生成的一個類的定義文件。
為了搞清楚窗體類的定義,以及界面功能的實現原理,下面分別分析各個文件的內容及其功能,以及它們是如何聯系在一起工作實現界面的創建與顯示的。
窗體類的頭文件 widget.h
在創建項目時,選擇窗體基類是 QWidget,在 widget.h 中定義了一個繼承自 QWidget 的類 Widget,下面是 widget.h 文件的內容與手動添加的注釋:
#ifndef WIDGET_H#define WIDGET_H#include namespace Ui { // 一個命名空間 Ui,包含一個類 Widget class Widget;}class?Widget?:?public?QWidget?// 繼承于?QWidget?的類?Widget?的定義{????Q_OBJECT?// 用?Qt?的信號與槽機制的類都必須加入的一個宏 public:?//?Widget?類的構造函數和析構函數 explicit Widget(QWidget *parent = 0); ~Widget(); private:????//?使用?Ui::Widget?定義的一個指針,指向可視化設計的界面 Ui::Widget *ui; };#endif窗體類的源文件 widget.cpp
源文件 widget.cpp 是類 Widget 的實現代碼,內容與手動添加的注釋如下:
#include "widget.h"#include "ui_widget.h" // 編譯生成的與 UI 文件 widget.ui 對應的類定義文件// 執行父類 QWidget 的構造函數,創建一個 Ui::Widget 類的對象 uiWidget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget){ // 實現窗口的生成與各種屬性的設置、信號與槽的關聯 ui->setupUi(this);}Widget::~Widget(){ delete ui; // 刪除用 new 創建的指針 ui}窗體界面定義文件 widget.ui
這是一個 XML 文件,定義了窗口上的所有組件的屬性設置、布局,及其信號與槽函數的關聯等。用 Qt Designer 可視化設計的界面都由 Qt 自動解析,并以 XML 文件的形式保存下來。在設計界面時,只需在 UI 設計器里進行可視化設計即可,而不用管 widget.ui 文件是怎么生成的。 widget.ui 文件的內容如下:
<?xml version="1.0" encoding="UTF-8"?><ui version="4.0"> <class>Widgetclass> <widget class="QWidget" name="Widget"> <property name="geometry"> <rect> <x>0x> <y>0y> <width>400width> <height>300height> rect> property> <property name="windowTitle"> <string>Widgetstring> property> <widget class="QLabel" name="label"> <property name="geometry"> <rect> <x>100x> <y>80y> <width>211width> <height>51height> rect> property> <property name="font"> <font> <pointsize>20pointsize> font> property> <property name="text"> <string>Hello, Worldstring> property> widget> <widget class="QPushButton" name="pushButton"> <property name="geometry"> <rect> <x>160x> <y>220y> <width>89width> <height>24height> rect> property> <property name="text"> <string>關閉string> property> widget> widget> <layoutdefault spacing="6" margin="11"/> <resources/> <connections> <connection> <sender>pushButtonsender> <signal>clicked()signal> <receiver>Widgetreceiver> <slot>close()slot> <hints> <hint type="sourcelabel"> <x>204x> <y>231y> hint> <hint type="destinationlabel"> <x>199x> <y>149y> hint> hints> connection> connections>ui>ui_widget.h 文件
對 widget.ui 文件進行編譯,會生成?ui_widget.h 文件。根據項目 shadow build 編譯設置不同,ui_widget.h 會出現在編譯后的目錄下,或與 widget.ui 同目錄。
注意:ui_widget.h 是對 widget.ui 文件編譯后自動生成的,widget.ui 又是通過 UI 設計器可視化設計生成的。所以,對 ui_widget.h 手工進行修改沒有什么意義,所有涉及界面的修改都應該直接在 Qt Designer 里進行。故 ui_widget.h 也沒有必要添加到項目里。
ui_widget.h 文件內容如下:
/**********************************************************************************?Form?generated?from?reading?UI?file?'widget.ui'**?Created?by:?Qt?User?Interface?Compiler?version?5.12.1** WARNING! All changes made in this file will be lost when recompiling UI file!********************************************************************************/#ifndef UI_WIDGET_H#define UI_WIDGET_H#include #include #include #include #include QT_BEGIN_NAMESPACEclass?Ui_Widget{public: QLabel *label; QPushButton *pushButton; void setupUi(QWidget *Widget){ if (Widget->objectName().isEmpty()) Widget->setObjectName(QString::fromUtf8("Widget")); Widget->resize(400, 300); label = new QLabel(Widget); label->setObjectName(QString::fromUtf8("label")); label->setGeometry(QRect(100, 80, 211, 51)); QFont font; font.setPointSize(20); label->setFont(font); pushButton = new QPushButton(Widget); pushButton->setObjectName(QString::fromUtf8("pushButton")); pushButton->setGeometry(QRect(160, 220, 89, 24)); retranslateUi(Widget); QObject::connect(pushButton, SIGNAL(clicked()), Widget, SLOT(close())); QMetaObject::connectSlotsByName(Widget); } // setupUi void retranslateUi(QWidget *Widget){ Widget->setWindowTitle(QApplication::translate("Widget", "Widget", nullptr)); label->setText(QApplication::translate("Widget", "Hello, World", nullptr)); pushButton->setText(QApplication::translate("Widget", "\345\205\263\351\227\255", nullptr)); } // retranslateUi};namespace Ui { class Widget: public Ui_Widget {};} // namespace UiQT_END_NAMESPACE#endif // UI_WIDGET_H文件 ui_widget.h 中主要做了以下的一些工作:
定義了一個 Ui_Widget 類,用于封裝可視化設計的界面;
自動生成了界面各個組件的類成員變量定義;
定義了 setupUi() 函數,這個函數用于創建各個界面組件,并設置其位置、大小、文字內容、字體等屬性,設置信號與槽的關聯;
定義 namespace Ui 以及定義一個從 Ui_Widget 繼承的 Widget 類。
提示:ui_widget.h 文件里實現界面功能的類是 Ui_Widget。再定義一個類 Widget 從 Ui_Widget 繼承而來,并定義在 namespace Ui 里,這樣 Ui::Widget 與 widget.h 里的類 Widget 同名,但是用 namespace 區分開來。所以,界面的 Ui::Widget 類與文件 widget.h 里定義的 Widget 類實際上是兩個類,但是 Qt 的處理讓用戶感覺不到 Ui::Widget 類的存在,只需要知道在 Widget 類里用 ui 指針可以訪問可視化設計的界面組件就可以了。
總結
以上是生活随笔為你收集整理的qt ui界面加入qsplitter_UI 文件设计与运行机制的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: python polygon函数_Pyt
 - 下一篇: tcp协议接收方对out of orde