高级控件
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::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顺序编辑模式。
模式 | 含义 |
编辑控件 | 在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对话框提供可选择文件、字体、颜色等多种状态的对话框类控件。
类型 | 说明 |
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::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::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::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::Nolcon | 不使用图标 |
QMessageBox::Question | 使用Question图标 |
QMessageBox::Information | 使用Information图标 |
QMessageBox::Warning | 使用Warning图标 |
QMessageBox::Critical | 使用Critical图标 |