可视化的图形化界面共有三种设计方式,一种是通过可视化来设计界面的方式;一种是代码化的设计方式;最后是混合上面两种的混合界面设计方式。目前我们只考虑通过Designer和代码来设计图形化页面的两种方式。
目录
可视化图形界面设计
图形页面设计
复选按钮
单选按钮
代码化图形界面设计
可视化图形界面设计
图形页面设计
可视化UI设计是使用QT中为我们提供的操作界面对我们的控件和结构进行直接排布而不需要进行代码操作的一种界面设计方式。例如我们需要创建如下的界面:
我们首先需要创建一个对话基类dialog,然后在创建出来的UI设计的界面将我们需要的单选按钮和复选按钮排布好,其中单选按钮是UI控件列表中的Radio Button而复选按钮是Check Button,但是普通的按钮就是push button。而中间是一个可以显示字体的字体框架,这里我们选择plain text edit。而plain text deit和 text edit 、line edit的区别如下:
名称 | plain text edit | text edit | line edit |
输入行数 | 单行 | 多行 | 多行 |
输出行数 | 不可限制最大行 | 可限制最大行 | 单行 |
用途 | 文本交互 | 信息展示 | 少量文本交互 |
根据上面的选择我们可以选定不同的控件,但是仅有控件还不够,我们还需要将一些控件放置到某些容器,如groupbox中。而groupbox是整个结构里面的小容器,有了它我们就可以将某些同类型的控件限定在一定的区域。然后再在容器或者整个控件内进行横向排序和垂直排序,这样不仅可以让容器排列整齐,还能够在我们创建出容器后对图形化界面进行拖拽时整个页面也会跟着动。
复选按钮
既然我们选择了按钮,但是如果我们不去设置一些机制处理按钮消息,那么这个按钮也是形同虚设。接下来我们要去设置处理消息响应,首先我们在UI界面右键点击复选按钮,选择转到槽,再根据是否需要点击判断的布尔变量而选择符合自己的函数,之后系统会帮我处理消息事件的方法。
如图,系统会帮助我们在dialog.h和dialog.cpp分别创建一个方法和方法的定义,然后我们就可以根据需要在该方法里面写入需要进行的操作。
void Dialog::on_rbutblue_clicked(bool checked)
{
}
-----------------------------------------------
private slots:
void on_rbutblue_clicked(bool checked);
单选按钮
单选按钮的操作和复选不同,单选按钮需要在我们创建对话框类调用构造函数时调用一个模拟信号槽实现接收机制并去处理的方法,然后还需要具体写一个方法对接收到的数据进行处理。
因为单选按钮是多个按钮执行一个功能,所以其必须是有一个共同的消息处理方法。首先我们在diaglog.h创建该消息处理方法的声明:
然后再在dialog.cpp文件中创建该声明对应的函数,创建的过程如下:
创建了dialog.cpp中的响应函数后,我们这里单选不同于复选,还需要再在类里面调用父类的一个按键消息传递和处理的函数。这个函数是connect,它起到的作用模仿我们在信号、槽里面实现的操作。所以它的第一个参数是发送消息的对象,第二个是信号的类型机制,第三个是接收者,这里就是类dialog,所以也就是this指针,最后就是消息处理方法,也就是我们刚才在.cpp中设置的函数。
QObject::connect(ui->rbutblue, SIGNAL(clicked()), this, SLOT(colorset()));
结合这些功能就能完成单选按钮功能。
代码化图形界面设计
在我们看完如何通过手动拖拽的形式设计一个页面后,接下来我们来看看如何用代码来实现我们之前手动拖拽的页面设计效果。
首先注意纯代码设计ui需要我们基类选择时就不去选择创建界面,这样我们创建出来的文件里面就不会包含.ui这个文件,也就不能使用手动页面设计的功能。
接下来就需要进行第一步的设置,那就是设置页面的结构和排布控件,因为用代码实现的控件里面没有groupbox,我们设置时就不能用这个框架了。接下来我们来看看需要哪些控件:首先两个普通按钮:确定和关闭;三个单选颜色按钮;三个复选格式按钮;一个字体框架和垂直约束和水平约束。而这些类将会以一个个指针的方式作为对话框类的对象而创建。
首先我们需要在存放类的头文件中引入这些控件的头文件并且声明这些控件的指针,而这些头文件很有规律,大多都是大写字母Q+这个控件的类型名称,而我们声明这些控件类型的指针时也是:(大写字母Q+控件类型名称)控件对象名称 * 指针名。
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include<QCheckBox>
#include<QPushButton>
#include<QPlainTextEdit>
#include<QRadioButton>
#include<QHBoxLayout>
#include<QVBoxLayout>
class Dialog : public QDialog
{
Q_OBJECT
private:
QCheckBox* underline;
QCheckBox* italic;
QCheckBox* blod;
QPushButton* close;
QPushButton* accept;
QPlainTextEdit* plaintextedit;
QRadioButton* green;
QRadioButton* yellow;
QRadioButton* blue;
QHBoxLayout* HBX1;
QHBoxLayout* HBX2;
QHBoxLayout* HBX3;
QVBoxLayout* VBX;
public:
Dialog(QWidget *parent = 0);
~Dialog();
};
#endif // DIALOG_H
在对话框头文件对控件进行声明完之后,我们就可以在源文件里面创建这些按钮了,利用new关键字在堆区开辟空间,然后让该控件类型的指针指向其即可。
这里我们创建了三个颜色复选按钮blue、green、yellow和三个字体单选按钮blod、italic、underline,两个普通按钮close、accept,这些按钮上面显示的对应名称就是开辟堆区空间时我们传入的字符串,但是这个字符串还需要用tr翻译。然后需要三个水平排序结构HBXn用来约束这三排按钮保持水平。还有一个负责文字显示的文字框plaintextedit和一个负责垂直排序好三个水平结构以及文字框垂直排序结构VBX。对于水平/垂直约束增加一个约束元素则用addlayout方法、增加一个控件元素就用addwidget方法。
最后再将整个约束放置到setLayout方法里面将约束和对话框关联起来即可,最后将这些属性设置都封装到一个初始化ui的方法setdialog里面。
#include "dialog.h"
void Dialog::setdialog()
{
VBX = new QVBoxLayout;
HBX1 = new QHBoxLayout;
HBX2 = new QHBoxLayout;
HBX3 = new QHBoxLayout;
blue = new QRadioButton(tr("蓝色"),this);
green = new QRadioButton(tr("绿色"),this);
yellow = new QRadioButton(tr("黄色"),this);
HBX1->addWidget(blue);
HBX1->addWidget(green);
HBX1->addWidget(yellow);
blod = new QCheckBox(tr("粗体"),this);
italic = new QCheckBox(tr("斜体"),this);
underline = new QCheckBox(tr("下划线"),this);
HBX2->addWidget(blod);
HBX2->addWidget(italic);
HBX2->addWidget(underline);
close = new QPushButton(tr("关闭"));
accept = new QPushButton(tr("确定"));
HBX3->addWidget(close);
HBX3->addWidget(accept);
plaintextedit = new QPlainTextEdit;
QFont font = plaintextedit->font();
font.setPointSize(20);
plaintextedit->setFont(font);
plaintextedit->setPlainText("你好!");
VBX->addLayout(HBX1);
VBX->addLayout(HBX2);
VBX->addStretch();
VBX->addWidget(plaintextedit);
VBX->addStretch();
VBX->addLayout(HBX3);
setLayout(VBX);
}
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
setdialog();
}
Dialog::~Dialog()
{
}
设置完控件我们可以运行查看这个页面了,但是此时这些按钮还不可用,我们需要对按钮进行设置消息响应和处理机制。
接下来我们就再添加和封装一个消息处理函数signal,这个消息处理函数就是里面就是设置不同的connect连接方法。这些方法都是一样的结构:
消息发送源、消息类型、接收对象、消息响应处理的槽函数
void Dialog::signal()
{
connect(close, SIGNAL(clicked()), this, SLOT(close()));
connect(accept, SIGNAL(clicked()), this, SLOT(accept()));
connect(blue, SIGNAL(clicked()), this , SLOT(SETCOLOR()));
connect(green, SIGNAL(clicked()), this , SLOT(SETCOLOR()));
connect(yellow, SIGNAL(clicked()), this , SLOT(SETCOLOR()));
connect(italic, SIGNAL(clicked(bool)), this , SLOT(SETITALIC(bool)));
connect(blod, SIGNAL(clicked(bool)), this , SLOT(SETBLOD(bool)));
connect(underline, SIGNAL(clicked(bool)), this , SLOT(SETUNDERLINE(bool)));
}
前面我们知道,信息响应后可以通过信息槽机制对相应的响应函数进行调用。
在继续学习下去之前我们需要具体了解一下信号槽机制。通常情况下,但我们点击了某个按钮,那么该点击信息将会以广播的形式向四周扩散,而我们设置的某个对象想要处理该信号就需要使用connect函数捕捉该信号并且调用槽(slot)里面的信息处理函数进行处理,这就是信号槽消息处理机制。
知道了这些后,我们就可以着手准备消息处理了,首先我们需要在对话框的类头文件中定义一个槽私密权限,并且在下面处理声明一些slot槽函数。而复选按钮需要每个按钮都是单独功能各自都需要一个槽函数,而单选按钮则所有按钮公用一个槽函数。
private slots:
void SETITALIC(bool clicked);
void SETUNDERLINE(bool clicked);
void SETBLOD(bool clicked);
void SETCOLOR();
因为每一个复选槽函数实现的机制都是一样的,只需要修改槽函数里面的字体细节即可,所以我们只看斜体处理的槽函数。因为我们修改的是字体框里面的字体,即需要一个符合我们需求的字体对象。所以第一步我们要新建一个字体对象并且获取之前字体框里面字体的属性;然后调用字体对象里面的设置字体斜体方法,传入判断所需的布尔变量。最后再利用setFont方法将我们新创建的字体对象放入字体框下面即可修改字体格式。类似地,如果我们想修改字体为粗体或者下划线,那么第二步时只需要调用相应的字体设置方法即可。
void Dialog::SETITALIC(bool clicked)
{
QFont font = plaintextedit->font();
font.setItalic(clicked);
plaintextedit->setFont(font);
}
但是对于单选,其共用一个槽函数。因为这里修改的是字体颜色,所我们需要新建的对象是调色板对象Palette,然后根据哪一个颜色按钮被点击而判断出哪一种颜色需要被设置到调色板,设置调色板需要两个参数:一个表示设置的是字体的颜色,一个表示设置的颜色。最后再将新建的调色板放入字体框即可。
void Dialog::SETCOLOR()
{
QPalette pal = plaintextedit->palette();
if(yellow->isChecked())
pal.setColor(QPalette::Text,Qt::yellow);
else if(blue->isChecked())
pal.setColor(QPalette::Text,Qt::blue);
else if(green->isChecked())
pal.setColor(QPalette::Text,Qt::green);
else
pal.setColor(QPalette::Text, Qt::black);
plaintextedit->setPalette(pal);
}
参考资料:
https://www.bilibili.com/video/BV1AX4y1w7Nt?p=5&vd_source=894e8817bba11b560ad040c21e7cfceb
https://blog.csdn.net/hanxiaoyong_/article/details/122785860