1)我们做这个project的意义是什么?
这篇笔记可以作为笔记(一)的一个补充,笔记(一)主要使用可视化UI完成项目的建立,这篇笔记则是用纯代码的方式建立与之相类似的程序和功能。那么,此次训练的目的也是帮助初学者更好的理解Qt这个软件到底该怎么去学习和使用,从底层代码的角度去思考如何制作一个程序。
2)第一个要关心的问题永远是软件的目的功能
和本人在Qt6 案例实战编程(一)中所要实现的功能类似,还是可以写入文本,对文本的字体和颜色进行修改,并且可以进行确定、取消和退出操作。软件预期目标效果如下:
图2.1 软件预期目标效果图
使用New File or Project对话框创建一个GUI项目,在向导中选择窗口基类为QDialog,但是不要勾选Generate from复选框,这样创建的项目里就没有窗口UI文件dialog.ui。
图2.2 创建项目时的具体操作
3)头文件dialog.h的编写
在头文件中,我们需要写入什么信息呢?当然,我们需要定义所需要的变量,并且对所要用到的函数进行声明。根据我们在预设计阶段所做的规划,我们发现我们总共需要三个Radio Button,三个Check Box Button,一个PlainTextEdit和三个PushButton,那么我们就对其下定义且命名:
private:
QCheckBox *chkBoxUnder;
QCheckBox *chkBoxItalic;
QCheckBox *chkBoxBold;
QRadioButton *radioBlack;
QRadioButton *radioRed;
QRadioButton *radioBlue;
QPlainTextEdit *txtEdit;
QPushButton *btnOK;
QPushButton *btnCancel;
QPushButton *btnClose;
注意这里加了一个private的标志,说明这些指针都是为dialog所有的,并不能被其他文件或者函数直接调用。并且我们所需要的函数功能函数定义如下:
private slots:
void do_chkBoxUnder(bool checked); //Underline
void do_chkBoxItalic(bool checked); //Italic
void do_chkBoxBold(bool checked); //Bold
void do_setFontColor(); //设置文字颜色
除此之外,手写代码编程的项目还需要自己手动加入ui和信号与槽的初始化,设定好void型函数分别为iniUI()和iniSignalSlots():
void iniUI(); //UI创建与初始化
void iniSignalSlots(); //初始化信号与槽的链接
那么我们总的头文件dialog.h就可以写成下面这样了:
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QCheckBox> //注意这里还是要加入各个组件的头文件的
#include <QRadioButton>
#include <QPlainTextEdit>
#include <QPushButton>
//#include <QVBoxLayout>
class Dialog : public QDialog
{
Q_OBJECT
private:
QCheckBox *chkBoxUnder;
QCheckBox *chkBoxItalic;
QCheckBox *chkBoxBold;
QRadioButton *radioBlack;
QRadioButton *radioRed;
QRadioButton *radioBlue;
QPlainTextEdit *txtEdit;
QPushButton *btnOK;
QPushButton *btnCancel;
QPushButton *btnClose;
void iniUI(); //UI创建与初始化
void iniSignalSlots(); //初始化信号与槽的链接
private slots:
void do_chkBoxUnder(bool checked); //Underline
void do_chkBoxItalic(bool checked); //Italic
void do_chkBoxBold(bool checked); //Bold
void do_setFontColor(); //设置文字颜色
public:
Dialog(QWidget *parent = nullptr);
~Dialog();
};
#endif // DIALOG_H
4)源文件dialog.cpp的编写
我们先对我们加入的组件指针进行一个设计吧,由于我们想使软件界面变得更美观,所以我们需要加入水平排列和垂直排列这两个头文件:
#include <QHBoxLayout>
#include <QVBoxLayout>
那么后面我们一步一步来,不妨先编辑一下字体吧!在头文件dialog.h中我们只是定义了三个属于QCheckBox的指针,但是还未对其做规定,所以我们需要在初始化时对他们做相应的用法规定。此外,对其位置也同样需要做如下说明:
//创建 Underline, Italic, Bold三个CheckBox,并水平布局
chkBoxUnder=new QCheckBox("Underline");
chkBoxItalic=new QCheckBox("Italic");
chkBoxBold=new QCheckBox("Bold");
QHBoxLayout *HLay1=new QHBoxLayout();
HLay1->addWidget(chkBoxUnder);
HLay1->addWidget(chkBoxItalic);
HLay1->addWidget(chkBoxBold);
对于颜色选择板块初始化如下(其中默认黑色被选中):
//创建 Black, Red, Blue三个RadioButton,并水平布局
radioBlack=new QRadioButton("Black");
radioBlack->setChecked(true); //缺省被选中
radioRed=new QRadioButton("Red");
radioBlue=new QRadioButton("Blue");
QHBoxLayout *HLay2=new QHBoxLayout;
HLay2->addWidget(radioBlack);
HLay2->addWidget(radioRed);
HLay2->addWidget(radioBlue);
对于确定,取消,退出三个按钮初始化如下:
//创建 确定, 取消, 退出 三个 PushButton, 并水平布局
btnOK=new QPushButton("确定");
btnCancel=new QPushButton("取消");
btnClose=new QPushButton("退出");
QHBoxLayout *HLay3=new QHBoxLayout;
HLay3->addStretch();
HLay3->addWidget(btnOK);
HLay3->addWidget(btnCancel);
HLay3->addStretch();
HLay3->addWidget(btnClose);
创建文本框,并对其初始化:
//创建 文本框,并设置初始字体
txtEdit=new QPlainTextEdit;
txtEdit->setPlainText("Hello world\n手工创建");
QFont font=txtEdit->font(); //获取字体
font.setPointSize(20); //修改字体大小为20
txtEdit->setFont(font); //设置字体
最后对整个窗口进行一个垂直对齐的操作:
//创建 垂直布局,并设置为主布局
// VLay=new QVBoxLayout(this);
QVBoxLayout *VLay=new QVBoxLayout(this);
VLay->addLayout(HLay1); //添加字体类型组
VLay->addLayout(HLay2); //添加字体颜色组
VLay->addWidget(txtEdit); //添加PlainTextEdit
VLay->addLayout(HLay3); //添加按键组
setLayout(VLay); //设置为窗口的主布局
综上所述我们得到的对ui界面的初始化函数iniUI()写为:
void Dialog::iniUI()
{
//创建 Underline, Italic, Bold三个CheckBox,并水平布局
chkBoxUnder=new QCheckBox("Underline");
chkBoxItalic=new QCheckBox("Italic");
chkBoxBold=new QCheckBox("Bold");
QHBoxLayout *HLay1=new QHBoxLayout();
HLay1->addWidget(chkBoxUnder);
HLay1->addWidget(chkBoxItalic);
HLay1->addWidget(chkBoxBold);
//创建 Black, Red, Blue三个RadioButton,并水平布局
radioBlack=new QRadioButton("Black");
radioBlack->setChecked(true); //缺省被选中
radioRed=new QRadioButton("Red");
radioBlue=new QRadioButton("Blue");
QHBoxLayout *HLay2=new QHBoxLayout;
HLay2->addWidget(radioBlack);
HLay2->addWidget(radioRed);
HLay2->addWidget(radioBlue);
//创建 确定, 取消, 退出 三个 PushButton, 并水平布局
btnOK=new QPushButton("确定");
btnCancel=new QPushButton("取消");
btnClose=new QPushButton("退出");
QHBoxLayout *HLay3=new QHBoxLayout;
HLay3->addStretch();
HLay3->addWidget(btnOK);
HLay3->addWidget(btnCancel);
HLay3->addStretch();
HLay3->addWidget(btnClose);
//创建 文本框,并设置初始字体
txtEdit=new QPlainTextEdit;
txtEdit->setPlainText("Hello world\n手工创建");
QFont font=txtEdit->font(); //获取字体
font.setPointSize(20); //修改字体大小为20
txtEdit->setFont(font); //设置字体
//创建 垂直布局,并设置为主布局
// VLay=new QVBoxLayout(this);
QVBoxLayout *VLay=new QVBoxLayout(this);
VLay->addLayout(HLay1); //添加字体类型组
VLay->addLayout(HLay2); //添加字体颜色组
VLay->addWidget(txtEdit); //添加PlainTextEdit
VLay->addLayout(HLay3); //添加按键组
setLayout(VLay); //设置为窗口的主布局
}
下一步,对信号和槽进行初始化,建立相应的连接,不再赘述,代码如下:
void Dialog::iniSignalSlots()
{
//三个设置颜色的 QRadioButton
connect(radioBlue,SIGNAL(clicked()),this,SLOT(do_setFontColor()));
connect(radioRed,SIGNAL(clicked()),this,SLOT(do_setFontColor()));
connect(radioBlack,SIGNAL(clicked()),this,SLOT(do_setFontColor()));
//三个设置字体的 QCheckBox
connect(chkBoxUnder,SIGNAL(clicked(bool)),this,SLOT(do_chkBoxUnder(bool)));
connect(chkBoxItalic,SIGNAL(clicked(bool)),this,SLOT(do_chkBoxItalic(bool)));
connect(chkBoxBold,SIGNAL(clicked(bool)),this,SLOT(do_chkBoxBold(bool)));
//三个按钮与窗口的槽函数关联
connect(btnOK,SIGNAL(clicked()),this,SLOT(accept()));
connect(btnCancel,SIGNAL(clicked()),this,SLOT(reject()));
connect(btnClose,SIGNAL(clicked()),this,SLOT(close()));
}
剩下按钮组件的函数描写与第一篇笔记的一样,如下:
void Dialog::do_chkBoxUnder(bool checked)
{
QFont font=txtEdit->font();
font.setUnderline(checked);
txtEdit->setFont(font);
}
void Dialog::do_chkBoxItalic(bool checked)
{
QFont font=txtEdit->font();
font.setItalic(checked);
txtEdit->setFont(font);
}
void Dialog::do_chkBoxBold(bool checked)
{
QFont font=txtEdit->font();
font.setBold(checked);
txtEdit->setFont(font);
}
void Dialog::do_setFontColor()
{
QPalette plet=txtEdit->palette();
if (radioBlue->isChecked())
plet.setColor(QPalette::Text,Qt::blue);
else if (radioRed->isChecked())
plet.setColor(QPalette::Text,Qt::red);
else if (radioBlack->isChecked())
plet.setColor(QPalette::Text,Qt::black);
else
plet.setColor(QPalette::Text,Qt::black);
txtEdit->setPalette(plet);
}
当然啦~最后还需要再调用并且析构一下这个函数:
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
iniUI(); //界面创建与布局
iniSignalSlots(); //信号与槽的关联
setWindowTitle("手工创建UI"); //设置窗口标题
}
Dialog::~Dialog()
{
}
5)测试与实现
最后我们按control+R或者F5来运行一下试试吧!测试一下各个按钮的功能是否正常~
图5.1 测试与实现