QT學習:04 代碼化的界面繪制


--- title: framework-cpp-qt-04-代碼化的界面繪制 EntryName: framework-cpp-qt-04-ui-design-by-code date: 2020-04-09 15:50:17 categories: tags: - qt - c/c++ ---

章節描述:

UI 的可視化設計是對用戶而言的,其實底層都是 C++ 的代碼實現,只是 Qt 巧妙地進行了處理,讓用戶省去了很多繁瑣的界面設計工作。

由於Qt界面設計的底層其實都是由 C++ 語言實現的,底層實現的功能比可視化設計更加強大和靈活。

創建無UI的項目

某些界面效果是可視化設計無法完成的,或者某些人習慣了用純代碼的方式來設計界面,就可以采用純代碼的方式設計界面,如 Qt 自帶的實例基本都是用純代碼方式實現用戶界面的。可視化UI設計與代碼化UI設計是可以混在一起的。
采用代碼設計實現 UI 時,需要對組件的布局有個完整的規划,不如可視化設計直觀,且編寫代碼工作量大。(建議在代碼化設計中,考慮事先使用一些產品文檔設計工具進行原型設計)
可視化UI設計與代碼化UI設計是可以混在一起的。但為了做出明顯的對比,我們使用無界面的工程作為起點。

首先建立一個 QT Widgets Appliation 項目 ,填寫有關項目信息。

我這里選擇的基類是QWidget,類名為Widget

不勾選“Generate form”(創建界面)復選框。

創建后的項目文件目錄樹下沒有 .ui 文件。

我們的目標是為了創建一個3個單選框,3個選擇框,1個編輯框的界面。

注意:與可視化設計得到的窗體類定義不同,Widget的類定義里沒有指向界面的指針 ui

編寫有關代碼

頭文件

在類的頭文件widget.h中,做以下步驟:

添加有關對象

為了靈活,我們使用指針的形式,等到必要時再實例化。

#include <QCheckBox>
#include <QRadioButton>

...
    
QCheckBox   	*chkBoxBold;
QRadioButton    *rBtnBlack;

添加 有關 的 槽

private slots:
	void on_chkBoxBold(bool checked); //Bold 的clicked(bool)信號的槽函數
	void setTextFontColor(); 		  //設置字體顏色

組件初始化

包括有關UI的創建、以及信號-槽的連接。

void    iniUI();			//UI 創建與初始化
void    iniSignalSlots();	//初始化信號與槽的連接

完整的頭文件

// widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

#include <QCheckBox>
#include <QRadioButton>
#include <QPlainTextEdit>
#include <QPushButton>

class Widget : public QWidget
{
    Q_OBJECT

private:
    QCheckBox   	*chkBoxUnder;
    QCheckBox   	*chkBoxItalic;
    QCheckBox   	*chkBoxBold;
    
    QRadioButton    *rBtnBlack;
    QRadioButton    *rBtnRed;
    QRadioButton    *rBtnBlue;
    
    QPlainTextEdit  *txtEdit;
    
    QPushButton     *btnClose;
    
    void    iniUI();//UI 創建與初始化
    void    iniSignalSlots();//初始化信號與槽的鏈接
    
private slots:
    void on_chkBoxUnder(bool checked); // Underline 的clicked(bool)信號的槽函數
    void on_chkBoxItalic(bool checked); // Italic 的clicked(bool)信號的槽函數
    void on_chkBoxBold(bool checked);  // Bold 的clicked(bool)信號的槽函數
    void setTextFontColor();  //設置字體顏色    
    
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
};
#endif // WIDGET_H

源文件

根據頭文件的情況,我們在源文件中給出具體的實現。

槽函數的實現

槽函數的功能與界面化設計時類似,只是在訪問界面組件時,無需使用 ui 指針,而是直接訪問 類里定義的界面組件的成員變量即可。

void Widget::on_chkBoxUnder(bool checked)
{
    QFont font=txtEdit->font();
    font.setUnderline(checked);
    txtEdit->setFont(font);
}

	..
    font.setBold(checked);

	..
    font.setItalic(checked);

界面組件的創建與布局

控件在布局時可以先不指定父窗口,最后交由Layout統一指定。

1)創建組件比較簡單,只需要new就可以了。

2)為了布局好看,需要添加一些布局(Layout),再將對應的組件加入布局中。

3)將布局加入一個"主"布局。

4)將"主布局"設置為窗體的主布局

void Widget::iniUI()
{
    //創建 Underline, Italic, Bold 3 個CheckBox,並水平布局
    chkBoxUnder = new QCheckBox(tr("Underline"));
    chkBoxItalic = new QCheckBox(tr("Italic"));
    chkBoxBold = new QCheckBox(tr("Bold"));

    QHBoxLayout *HLay1 = new QHBoxLayout;

    HLay1->addWidget(chkBoxUnder);
    HLay1->addWidget(chkBoxItalic);
    HLay1->addWidget(chkBoxBold);

    //創建 Black, Red, Blue 3 個RadioButton,並水平布局
    rBtnBlack = new QRadioButton(tr("Black"));
    rBtnBlack->setChecked(true);
    rBtnRed = new QRadioButton(tr("Red"));
    rBtnBlue = new QRadioButton(tr("Blue"));
    QHBoxLayout *HLay2 = new QHBoxLayout;
    HLay2->addWidget(rBtnBlack);
    HLay2->addWidget(rBtnRed);
    HLay2->addWidget(rBtnBlue);
    //創建 退出PushButton, 並水平布局
    btnClose = new QPushButton(tr("Close"));

    QHBoxLayout *HLay3 = new QHBoxLayout;

    HLay3->addStretch();
    HLay3->addWidget(btnClose);
    //創建文本框,並設置初始字體
    txtEdit = new QPlainTextEdit;
    txtEdit->setPlainText("Hello world\n\nIt is my demo");
    QFont font = txtEdit->font(); //獲取字體
    font.setPointSize(20);//修改字體大小
    txtEdit->setFont(font);//設置字體
    //創建垂直布局,並設置為主布局
    QVBoxLayout *VLay = new QVBoxLayout;
    VLay->addLayout(HLay1); //添加字體類型組
    VLay->addLayout(HLay2);//添加字體顏色組
    VLay->addWidget(txtEdit);//添加PlainTextEdit
    VLay->addLayout(HLay3);//添加按鍵組
    setLayout(VLay); //設置為窗體的主布局
}

關聯信號槽

void Widget::iniSignalSlots()
{
    //三個顏色 QRadioButton 的clicked()信號與setTextFontColor()槽函數關聯
    connect(rBtnBlue,SIGNAL(clicked()),this,SLOT(setTextFontColor()));
    connect(rBtnRed,SIGNAL(clicked()),this,SLOT(setTextFontColor()));
    connect(rBtnBlack,SIGNAL(clicked()),this,SLOT(setTextFontColor()));
    //三個字體設置的 QCheckBox 的clicked(bool)信號與相應的槽函數關聯
    connect(chkBoxUnder,SIGNAL(clicked(bool)),
            this,SLOT(on_chkBoxUnder(bool)));
    connect(chkBoxItalic,SIGNAL(clicked(bool)),
            this,SLOT(on_chkBoxItalic(bool)));
    connect(chkBoxBold,SIGNAL(clicked(bool)),
            this,SLOT(on_chkBoxBold(bool)));
    //按鈕的信號與窗體的槽函數關聯
    connect(btnClose,SIGNAL(clicked()),this,SLOT(close()));
}

組件初始化

我們將組件初始化的調用放在構造函數中。

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    iniUI(); //界面創建與布局
    iniSignalSlots(); //信號與槽的關聯
    setWindowTitle("Form created mannually");
}

完整的源文件

// widget.cpp

#include <QHBoxLayout>
#include <QVBoxLayout>
#include "widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    iniUI(); //界面創建與布局
    iniSignalSlots(); //信號與槽的關聯
    setWindowTitle("Form created mannually");
}

Widget::~Widget()
{
}

void Widget::on_chkBoxUnder(bool checked)
{
    QFont font=txtEdit->font();
    font.setUnderline(checked);
    txtEdit->setFont(font);
}

void Widget::on_chkBoxItalic(bool checked)
{
    QFont font=txtEdit->font();
    font.setItalic(checked);
    txtEdit->setFont(font);
}

void Widget::on_chkBoxBold(bool checked)
{
    QFont font=txtEdit->font();
    font.setBold(checked);
    txtEdit->setFont(font);
}

void Widget::setTextFontColor() //設置字體顏色
{
    QPalette plet=txtEdit->palette();
    if (rBtnBlue->isChecked())
        plet.setColor(QPalette::Text,Qt::blue);
    else if (rBtnRed->isChecked())
        plet.setColor(QPalette::Text,Qt::red);
    else if (rBtnBlack->isChecked())
        plet.setColor(QPalette::Text,Qt::black);
    else
        plet.setColor(QPalette::Text,Qt::black);
    txtEdit->setPalette(plet);
}


void Widget::iniUI()
{
    //創建 Underline, Italic, Bold 3 個CheckBox,並水平布局
    chkBoxUnder = new QCheckBox(tr("Underline"));
    chkBoxItalic = new QCheckBox(tr("Italic"));
    chkBoxBold = new QCheckBox(tr("Bold"));

    QHBoxLayout *HLay1 = new QHBoxLayout;

    HLay1->addWidget(chkBoxUnder);
    HLay1->addWidget(chkBoxItalic);
    HLay1->addWidget(chkBoxBold);

    //創建 Black, Red, Blue 3 個RadioButton,並水平布局
    rBtnBlack = new QRadioButton(tr("Black"));
    rBtnBlack->setChecked(true);
    rBtnRed = new QRadioButton(tr("Red"));
    rBtnBlue = new QRadioButton(tr("Blue"));
    QHBoxLayout *HLay2 = new QHBoxLayout;
    
    HLay2->addWidget(rBtnBlack);
    HLay2->addWidget(rBtnRed);
    HLay2->addWidget(rBtnBlue);
    
    //創建 退出PushButton, 並水平布局
    btnClose = new QPushButton(tr("Close"));

    QHBoxLayout *HLay3 = new QHBoxLayout;

    HLay3->addStretch();
    HLay3->addWidget(btnClose);
    //創建文本框,並設置初始字體
    txtEdit = new QPlainTextEdit;
    txtEdit->setPlainText("Hello world");
    QFont font = txtEdit->font(); //獲取字體
    font.setPointSize(20);//修改字體大小
    txtEdit->setFont(font);//設置字體
    //創建垂直布局,並設置為主布局
    QVBoxLayout *VLay = new QVBoxLayout;
    
    VLay->addLayout(HLay1); //添加字體類型組
    VLay->addLayout(HLay2);//添加字體顏色組
    VLay->addWidget(txtEdit);//添加PlainTextEdit
    VLay->addLayout(HLay3);//添加按鍵組
    
    setLayout(VLay); //設置為窗體的主布局
}

void Widget::iniSignalSlots()
{
    //三個顏色 QRadioButton 的clicked()信號與setTextFontColor()槽函數關聯
    connect(rBtnBlue,SIGNAL(clicked()),this,SLOT(setTextFontColor()));
    connect(rBtnRed,SIGNAL(clicked()),this,SLOT(setTextFontColor()));
    connect(rBtnBlack,SIGNAL(clicked()),this,SLOT(setTextFontColor()));
    //三個字體設置的 QCheckBox 的clicked(bool)信號與相應的槽函數關聯
    connect(chkBoxUnder,SIGNAL(clicked(bool)),
            this,SLOT(on_chkBoxUnder(bool)));
    connect(chkBoxItalic,SIGNAL(clicked(bool)),
            this,SLOT(on_chkBoxItalic(bool)));
    connect(chkBoxBold,SIGNAL(clicked(bool)),
            this,SLOT(on_chkBoxBold(bool)));
    //按鈕的信號與窗體的槽函數關聯
    connect(btnClose,SIGNAL(clicked()),this,SLOT(close()));
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM