创建无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()));
}