創建無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()));
}
