Qt入門之UI文件設計與運行機制

Qt入門之UI文件設計與運行機制

QMainWindow 是主窗口類,主窗口具有主菜單欄,工具欄和狀態欄,類似於一般的應用程序的窗口

QWidget是所有具體可視界面類的基類,選擇QWidget 創建的界面對各種界面組件都可以支持

QDialog是對話框類,可建立一個基於對話框的界面

項目文件組成

1.項目組織文件samp2_1.pro,存儲項目設置的文件

#表示加入了 core gui模塊。 core gui是Qt用於GUI設計的類庫模板,如果創建的是控制檯(console)應用程序,就不需要加入 core gui
#Qt類庫以模塊的形式組織各種功能的類,根據項目涉及的需求,在項目中添加適當的類庫模塊支持,例如,如果項目中使用到了設計數據庫操作的類就需要用到sql的模塊,在pro文件中需要增加如下一行
#QT       +=sql
QT       += core gui

#這是個條件執行語句,表示當QT的版本大於4時,才加入widgets模塊
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

#表示生產的目標可執行文件的名稱,即編譯後的可執行文件是samp2_1.exe
TARGET = samp2_1
#表示項目使用的模板是app,是一般的應用程序
TEMPLATE = app

CONFIG += c++11

#SOURCES 、HEADERS 、FORMS 記錄了項目中包含的源程序文件、頭文件和窗體文件(.ui文件)的名稱。這些文件列表是Qt Creator自動添加到項目管理文件裏面的,用戶不需要手動修改。當從項目添加或刪除一個文件時,項目管理文件的條目會自動修改
SOURCES += \
        main.cpp \
        widget.cpp

HEADERS += \
        widget.h

FORMS += \
        widget.ui

2.主函數文件main.cpp

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

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);   //Qt的標準應用程序類
    Widget w;    //定義並創建窗口
    w.show();    //顯示窗口

    return a.exec();    //啓動應用程序的執行,開始應用程序的消息循環和事件處理
}

3.窗體相關文件

將項目編譯,編譯後在項目目錄下會自動生成一個ui_widget.h文件(在編譯後的文件夾裏),這樣,對於一個窗體,就有4個文件了 :

widget.h   定義窗體類的頭文件,定義了類Widget

widget.cpp   Widget類的功能實現源程序文件

widget.ui     窗體界面文件,

ui_widget.h  編譯後,根據窗體上的組件及屬性、信號與槽的關聯等自動生成的一個類的定義文件,類的名稱是Ui_Widget

下面分析各個文件的內容及其功能,以及他們是如何聯繫到一起工作,實現界面的創建與顯示的。

3.1 widget.h文件

widget.h文件是窗體類的頭文件。在創建項目時,選擇窗體基類的QWidget,在widget.h中定義一個繼承自QWidget的類的Widget:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;       //聲明瞭一個名稱爲 Ui 的命名空間,包含一個類Widget。但這個Widget類並不是本文件裏定義的類Widget,而是ui_widget.h文件中定義的類,用於描述組件的。這個聲明相當與一個外部聲明(具體看完ui_widget.h文件才能搞明白)
}

class Widget : public QWidget    //本實例窗口類Widget的定義
{
    Q_OBJECT    //使用Qt的信號與槽機制都必須加入的宏

public:
    explicit Widget(QWidget *parent = nullptr);    //構造函數
    ~Widget();    //析構函數

private:
    Ui::Widget *ui;     //這個指針是用前面namespace Ui裏的Widget類定義的,所以指針ui指向可視化設計的界面,要訪問界面上的組件,都需要通過這個ui指針
};

#endif // WIDGET_H

3.2 widget.cpp文件

widget.cpp文件是類Widget的實現代碼:

#include "widget.h"
#include "ui_widget.h"      //Qt編譯生產的與UI文件widget.ui對應的類定義文件

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)      //執行父類QWidget的構造函數,創建一個Ui::Widget類的對象ui,這個ui就是Widget的private部分定義的指針變量ui。可參考:https://blog.csdn.net/GouplovXim1314/article/details/104349423
{
    ui->setupUi(this);      //這個函數實現了窗口的生產與各種屬性的設置、信號與槽的關聯
}

Widget::~Widget()
{
    delete ui;    //析構函數
}

所以,在 ui_widget.h 文件裏有一個 namespace 名稱爲 Ui,裏面有一個類 Widget 類用於描述可視化的窗體,且與widget.h裏定義的類同名。在Widget類裏訪問 Ui::Widget類的成員變量或函數需要通過Widget類裏的 ui 指針,如果構造函數裏執行 ui->setupUi(this)函數那樣。

3.3 ui_widget.h文件

ui_widget.h文件是在對 widget.ui 文件編譯後生成的一個文件,ui_widget.h會出現在編譯後的目錄下,或與widget.ui同目錄(與項目的 shadow build編譯設置有關)。

文件ui_widget.h並不會出現在 Qt Creator 的項目文件目錄樹裏,可手動添加

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

#ifndef UI_WIDGET_H
#define UI_WIDGET_H

#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QLabel>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_Widget
{
public:
    QLabel *label;
    QPushButton *btnClose;

    void setupUi(QWidget *Widget)
    {
        if (Widget->objectName().isEmpty())
            Widget->setObjectName(QStringLiteral("Widget"));
        Widget->resize(400, 300);
        QFont font;
        font.setFamily(QStringLiteral("Aharoni"));
        font.setPointSize(12);
        font.setBold(true);
        font.setWeight(75);
        Widget->setFont(font);
        label = new QLabel(Widget);
        label->setObjectName(QStringLiteral("label"));
        label->setGeometry(QRect(120, 110, 91, 31));
        label->setFont(font);
        btnClose = new QPushButton(Widget);
        btnClose->setObjectName(QStringLiteral("btnClose"));
        btnClose->setGeometry(QRect(240, 210, 75, 23));

        retranslateUi(Widget);
        QObject::connect(btnClose, SIGNAL(clicked()), Widget, SLOT(close()));

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

    void retranslateUi(QWidget *Widget)
    {
        Widget->setWindowTitle(QApplication::translate("Widget", "Widget", Q_NULLPTR));
        label->setText(QApplication::translate("Widget", "Hello Word", Q_NULLPTR));
        btnClose->setText(QApplication::translate("Widget", "\345\205\263\351\227\255", Q_NULLPTR));
    } // retranslateUi

};

namespace Ui {
    class Widget: public Ui_Widget {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_WIDGET_H

查看ui_widget.h文件,發現他主要做了一下工作:

(1)定義了一個類Ui_Widget,用於封裝可視化界面的設計

(2)自動生成了界面各個組件的類成員變量定義。在 public 部分爲界面上每個組件定義了一個指針變量,變量的名稱就是設置的objectName。比如,在窗體上放置一個QLabel 和 一個QPushButton並命名後,會自動生成定義是:QLabel *LabDemo; QPushButton *btnClose;

(3)定義了setupUi()函數,這個函數用來創建各個界面組件,並設置其位置、大小、文字內容、字體等屬性,設置信號與槽的關聯。

  • setupUi()函數體的第一部分是根據可視化設計界面內容,用C++代碼 創建界面上的個組件,並設置其屬性。
  • 接下來,setupUi()調用了函數 retranslateUi(Widget),用來設置界面各組件的文字內容屬性,如標籤的文字、按鍵的文字、窗體的標題等。將界面上的文字內容獨立出來作爲一個函數retranslateUi(),在設計多語言界面時會用到這個函數。
  • setupUi()函數的第三部分是設置信號與槽的關聯,本文件中有以下兩行:

    QObject::connect(btnClose, SIGNAL(clicked()), Widget, SLOT(close()));

    QMetaObject::connectSlotsByName(Widget);

    第一行是調用 connect() 函數,將在UI設計器裏設置的信號與槽的關聯轉換爲語句。

    第二行是設置槽函數的關聯方式,用於將UI設計器自動生產的組件信號的槽函數與組件信號關聯

    所以:在Widget 的構造函數裏調用 ui->setupUi(this),就實現了窗體上組件的創建、屬性設置、信號與槽的關聯

  • 定義 namespace Ui,並定義一個從 Ui_Widget 繼承的類 Widget

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章