【Qt】Qt的GUI设计与制作(下篇:高级控件、Qt Designer、对话框)

版权声明:本文为博主原创文章,允许转载,但希望标注转载来源。 https://blog.csdn.net/qq_38410730/article/details/80745231

高级控件

Qt为了方便GUI的设计,不仅仅提供了QPushButton、QLabel这样的单一控件,还提供了可以将多个控件功能合为一体的高级控件类。如:显示日历的QCalendarWidget类,还提供了将多个控件功能融为一体的控件。

QCalendarWidget

QCalendarWidget控件提供了将当前系统时间(年/月)日期显示为日期格式的GUI。可以当前时间为基础显示日历,也可以通过成员函数设置要显示的年/月。

此空间可以通过鼠标或者键盘移动日期,也可以利用成员函数selectdDate()获取在控件上选择的日期的信息,还可以通过属性参数minimunDate()和maximunDate()获取当前月份的第一天和最后一天。

calendar=new QCalendarWidget(this);
calendar->setGridVisible(true);

声明QCalendarWidget之后,可以获取当前日期的年/月信息,并提供GUI。同样,也可以设置特定范围内的起始日:

calendar->setMinimumDate(QDate(2000,1,1));
calendar->setMaximumDate(QDate(2020,1,1));

同样还可以在QCalendarWidget重处理单击信息时间,选择日期后,可以关联信号时间函数selectionChanged()与槽函数,还可以通过一下常量改变QCalendarWidget标题行的显示风格。

QCalendarWidget标题显示风格
常量 含义
QCalendarWidget::SingleLetterDayNames 1 显示星期首字母
QCalendarWidget::ShortDayNames 2 显示星期缩写
QCalendarWidget::LongDayNames 3 显示星期完整拼写
QCalendarWidget::NoHorizontalHeader 0 不水平显示标题行

使用Designer构建GUI

Designer简介

使用Qt提供的Designer工具,可以不编写代码也可以设计GUI。同时,使用Designer工具布局的控件也实现信号与槽的关联。

这款工具的工作原理就是,首先转换为使用Designer设计的GUI XML文件,再利用qmake转换为代码,然后进行编译。

编辑模式

Qt Designer提供了空间编辑模式、信号与槽编辑模式、伙伴编辑模式和Tab顺序编辑模式。

Qt编辑模式
模式 含义
编辑控件 在GUI窗体上添加控件和界面布局,编辑控件属性
编辑信号与槽 已布局的控件和信号与槽相连接
编辑伙伴 通过包含到标签控件的快捷键分配键盘焦点
编辑Tab顺序 不同Tab按顺序移动控件的窗口焦点

布局管理功能

Designer设计GUI时,不仅仅可以利用绝对坐标通过鼠标布局控件,也可以使用布局管理器。下图提供了两种方式:

预览功能

Qt Designer支持预览功能,一查看设计的GUI的效果。在使用Designer设计GUI的过程中,可以通过此功能快捷键预览GUI。还可以使用快捷键Ctrl+R进行预览。

使用容器类控件

使用Designer时,可以使用Qt提供的容器类控件。例如:在组合框中可以设计包含QCheckBox控件的GUI。下图提供了两种方式:

设计主窗口

Designer不仅仅可以用单一控件设计GUI,还可以提供设计多个GUI的主窗口(Main Window)。可以向主窗口添加菜单,藿香菜单添加特定控件。

信号与槽的使用

这里使用Designer来设计信号与槽的使用,一共提供两种方法。下面以一个简单的例子分别说明这两个方法的内容:

程序定义

在定义每一个控件的时候,窗口右下会对这个控件进行设置。比如:控件名、大小、位置等等。

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

public slots:                                           //槽函数
    void slider_valueChanged(int value);

private:
    Ui::Widget *ui;                                //连接Designer创建的GUI的桥梁
};

#endif // WIDGET_H

当我们在Designer中定义一个控件,那么在程序中使用“ui->”就能直接引用该对象。并且该对象不需要在程序中进行定义声明,ui会自动生成这一切!

也就是说,在程序中使用Designer中定义的控件,都必须使用“ui->”来进行引用。

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    connect(ui->horizontalSlider,SIGNAL(valueChanged(int)),this,SLOT(slider_valueChanged(int)));        //槽函数
}

void Widget::slider_valueChanged(int value){                    //定义槽函数
    ui->spinBox->setValue(value);
}

Widget::~Widget()
{
    delete ui;
}

这里需要注意一点:connect()的槽函数必须声明在“ui->setupUi(this)”之后,不然会出现错误!

Designer定义

除了使用程序定义之外,也可以使用Designer带有的工具来进行信号与槽的连接。

单击Qt Creator的“编辑(Edit)”菜单,在弹出的子菜单里面点选“编辑信号/槽(Edit signals/slots)”,此时,当鼠标移动到某个控件上时,该控件的颜色变成红色。然后单击信号控件,拖动鼠标到槽控件:

就可以选择信号函数和对应的槽函数了。

这种方式虽然避免了程序的编写,但是槽函数没有什么选择权,都是比较简单。没有太多的可能性。除非是非常简单的功能,否则很有可能时实现不了的。

如果想要退出该模式,单击Qt Creator的“编辑(Edit)”菜单,在弹出的子菜单里面点选“编辑widget(Edit widgets)”。

对话框

对话框提供了允许用户输入值的GUI。例如,可以在基于主窗口或单窗口的应用程序上创建新对话框并输入值。

普通对话框

Qt对话框提供可选择文件、字体、颜色等多种状态的对话框类控件。

Qt对话框控件类型
类型 说明
QInputDialog 用户可以输入值的对话框
QColorDialog 可以选择指定颜色的对话框
QFileDialog 提供选择文件或目录的GUI的对话框
QFontDialog 可以选择字体的对话框
QMessageBox 模式对话框,通过主窗口传送用户所选项目的返回值(如:确定、取消)
QProcessDialog 显示百分比进度的对话框

QInputDialog

QInputDialog提供接收用户输入值的对话框。输入值可以是整数、实数或者QString的字符串。

bool retValue;
int i = QInputDialog::getInt(this,tr("input"),tr("number"),0,0,100,1,&retValue);            //A

if(retValue){
        qDebug("true. %d",i);
}else{
        qDebug("false.");
}

只需要这一段代码,除了头文件之外,其他什么都不需要添加。也就是,不需要new,就能生成一个对话框。

解释一下A行:

getInt()表示接受整数值的对话框。参数:指定父类、窗体的标题、输入值控件的标签、默认设定值、输入范围最小值、输入范围最大值、对话框的的STEP、查看是否点击了对话框的“OK”或者“Cancel”。

为什么要设置最后一项呢?

如果用户取消了,但是i仍然能接收到一个数字(默认设定值)。

而对于getDouble()就比较类似,不赘述了。

讲一下getItem()函数,是接受下拉框选择的值:

QStringList items;                                                //字符串列表
items<<tr("Spring")<<tr("Summer")<<tr("Fall")<<tr("Winter");

bool ok;
QString item = QInputDialog::getItem(this,tr("Input"),tr("Season"),items,0,false,&ok);

if(ok&&!item.isEmpty()){
        qDebug()<<item;
}

这段程序的运行结果为:

再讲一下getText()函数,是接收字符串的值:

bool ok;
QString text = QInputDialog::getText(this,tr("Input"),tr("Text"),QLineEdit::Normal,tr("Username"),&ok);

if(ok&&!text.isEmpty()){
        qDebug()<<text;
}

这段程序的运行结果为:

QColorDialog

QColorDialog是用户选择颜色的对话框。

QColor color;
color = QColorDialog::getColor(Qt::blue,this,"Color:",QColorDialog::DontUseNativeDialog);

if(color.isValid()){
        qDebug()<<color.name();
}

这段程序的运行结果为:

解释一下getColor()的各个参数:QColorDialog的默认颜色、指定父类、对话框标题栏,指定option值。其中可以指定的option的值有:

QColorDialog各常量
常量 说明
QColorDialog::ShowAlphaChannel 1 可以选择alpha值
QColorDialog::NoButtons 2 不显示OK和CANCEL按钮

QFontDialog

QFontDialog是用户可以选择字体的对话框。

bool ok;
QFont font = QFontDialog::getFont(&ok,QFont("宋体"),this);

if(ok){
        qDebug()<<font.key();
}

这段程序的运行结果为:

QFileDialog

QFileDialog是提供用户可以进行打开、保存、选择目录等文件处理的对话框。

可以使用成员函数getOpenFileName()选择原始文件;使用成员函数getOpenFileNames()选择多个目录内的多个文件;使用成员函数getExistingDirectory()选择目录;使用成员函数getSaveFileName()指定要保存的文件的对话框功能。

getExistingDirectory()选择目录

QFileDialog::Options options;
options = QFileDialog::DontResolveSymlinks|QFileDialog::ShowDirsOnly;
options |= QFileDialog::DontUseNativeDialog;

QString directory = QFileDialog::getExistingDirectory(this,tr("File:"),"/home",options);
qDebug()<<directory;

这段程序运行的结果为:

这里讲一下QFileDialog的options常量值:

QFileDialog各常量值
常量 说明
QFileDialog::ShowDirsOnly 1 只显示目录
QFileDialog::DontResolveSymlinks 2 不显示符号链接
QFileDialog::DontConfirmOverwrite 3 覆写现存文件时,不显示警告信息
QFileDialog::DontUseNativeDialog 10 不使用系统默认文件对话框
QFileDialog::ReadOnly 20 使用只读模式文件对话框
QFileDialog::HideNameFilterDetails 40 使用过滤器隐藏文件

getOpenFileName()选择单个文件

QFileDialog::Options options;
options |= QFileDialog::DontUseNativeDialog;

QString selectedFilter;
QString fileName = QFileDialog::getOpenFileName(this,tr("File"),"/",tr("All Files (*);;Picture Files (*.jpg);;Text Files (*.txt)"),&selectedFilter,options);

qDebug()<<fileName;
qDebug()<<selectedFilter;

这段程序的运行结果为:

解释一下getOpenFileName()的各个参数:指定父类、对话框的标题、对话框起始的目录、可选择的文件类型、用户选择的文件类型、options常量值。

注意一下:在编辑可选择的文件类型时,每两个不同的文件类型之间用“;;”隔开,是两个分号隔开

getSaveFileName()指定要保存的文件

QFileDialog::Options options;
options |= QFileDialog::DontUseNativeDialog;

QString selectedFilter;
QString fileName = QFileDialog::getSaveFileName(this,tr("File:"),".txt",tr("ALL Files (*);;Text Files (*.txt)"),&selectedFilter,options);

qDebug()<<fileName;
qDebug()<<selectedFilter;

这段程序运行的结果为:

QMessageBox

QMessageBox是提供模式对话框的类。向用户显示信息,并能接收以下按钮输入。

QMessageBox各按钮常量值
常量 说明
QMessageBox::Ok OK按钮
QMessageBox::Open 打开文件按钮
QMessageBox::Save 保存按钮
QMessageBox::Cancel 取消按钮
QMessageBox::Close 关闭按钮
QMessageBox::Discard 不保存且放弃按钮
QMessageBox::Apply 请求按钮
QMessageBox::Reset 重置按钮
QMessageBox::RestoreDefaults 重新保存按钮
QMessageBox::Help 帮助按钮
QMessageBox::SaveAll 全部保存按钮
QMessageBox::Yes Yes按钮
QMessageBox::YesToAll 全部执行Yes按钮
QMessageBox::No No按钮
QMessageBox::NoToAll 全部执行No按钮
QMessageBox::Abort 停止按钮
QMessageBox::Retry 重试按钮
QMessageBox::Ignore 忽略按钮
QMessageBox::NoButton 无效按钮

critical()消息框

QMessageBox::StandardButton reply;
reply = QMessageBox::critical(this,tr("Message"),"There is no a fisk.",QMessageBox::Abort|QMessageBox::Retry|QMessageBox::Ignore);

if(reply==QMessageBox::Abort){
        qDebug("Abort");
}else if(reply==QMessageBox::Ignore){
        qDebug("Ignore");
}else{
        qDebug("Retry");
}

这段程序的运行结果为:

information()消息框

QMessageBox::StandardButton reply;
reply = QMessageBox::information(this,tr("Message"),"There is no a fisk.");

if(reply==QMessageBox::Ok){
        qDebug("Ok");
}

这段程序的运行结果为:

由于information()消息框只是传递消息,默认有一个OK按钮,就无需手动添加了。

Question()消息框

QMessageBox::StandardButton reply;
reply = QMessageBox::question(this,tr("Message"),"Do you save this file?",QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel);

if(reply==QMessageBox::Yes){
        qDebug("Yes");
}else if(reply==QMessageBox::No){
        qDebug("No");
}else{
        qDebug("Cancel");
}

这段程序的运行结果为:

warning()对话框

QMessageBox::StandardButton reply;
reply = QMessageBox::warning(this,tr("Message"),"There is no a fisk.",QMessageBox::Abort|QMessageBox::Retry|QMessageBox::Ignore);

if(reply==QMessageBox::Abort){
        qDebug("Abort");
}else if(reply==QMessageBox::Ignore){
        qDebug("Ignore");
}else{
        qDebug("Retry");
}

这段程序的运行结果为:

当然,上面的都是使用定义好的按钮,还有一种方式,可以自己定义按钮的显示内容。

QMessageBox msgBox(QMessageBox::Warning,tr("Message"),"是否保存?",0,this);
msgBox.addButton(tr("是"),QMessageBox::AcceptRole);
msgBox.addButton(tr("否"),QMessageBox::RejectRole);

if(msgBox.exec()==QMessageBox::AcceptRole){
        qDebug("保存");
}else{
        qDebug("不保存");
}

这段程序的运行结果为:

尽管可以自定义按钮的显示内容,但是QMessageBox上面的图标还是只能是以下四种:

QMessageBox图标常量
常量 说明
QMessageBox::Nolcon 不使用图标
QMessageBox::Question 使用Question图标
QMessageBox::Information 使用Information图标
QMessageBox::Warning 使用Warning图标
QMessageBox::Critical 使用Critical图标

猜你喜欢

转载自blog.csdn.net/qq_38410730/article/details/80745231