进度条
通常在处理长时间任务时需要提供进度条用于显示时间。
进度条对话框的使用方法有两种,即模态方式与非模态方式。
模态方式的使用比较简单方便,但必须使用QApplication::processEvents()使事件循环保持正常进行状态,从而确保应用不会阻塞。若使用非模态方式,则需要通过QTimer实现定时设置进度条的值。
Qt 提供了两种显示进度条的方式:
- QProgessBar,提供了一种横向或纵向显示进度的控件表示方式,用来描述任务的完成情况;
- QProgessDialog,提供了一种针对慢速过程的进度条对话框表示方式,用于描述任务完成的进度情况。
示例
使用一个进度条示例来进行进度条的演示
步骤
- 新建Qt Widgets Application项目,项目名称为“Progress”,基类选择“QDialog”,类名命名为“ProgressDlg”,取消“创建界面”复选框。
- 在progressdlg.h中添加以下代码
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QLabel>
#include <QProgressBar>
#include <QComboBox>
#include <QPushButton>
#include <QGridLayout>
#include <QLineEdit>
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog(QWidget *parent = nullptr);
~Dialog();
private slots:
void startProgress();
private:
QLabel *FileNum;
QLineEdit *FileNumLineEdit;
QLabel *ProgressType;
QComboBox *comBox;
QProgressBar *progressBar;
QPushButton *startBtn;
QGridLayout *mainLayout;
};
#endif // DIALOG_H
- progressdlg.cpp文件中内容如下:
#include "dialog.h"
#include <QProgressDialog>
#include <QFont>
#include <QDebug>
#include <QThread>
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
QFont font("ZYSong18030", 12);
setFont(font);
setWindowTitle(tr("Progress"));
FileNum = new QLabel(tr("文件数目:"));
FileNumLineEdit = new QLineEdit;
FileNumLineEdit->setText(tr("10000"));
ProgressType = new QLabel(tr("显示类型:"));
comBox = new QComboBox;
comBox->addItem(tr("progressBar"));
comBox->addItem(tr("ProgressDialog"));
progressBar = new QProgressBar;
startBtn = new QPushButton(tr("开始"));
mainLayout = new QGridLayout(this);
mainLayout->addWidget(FileNum, 0, 0);
mainLayout->addWidget(FileNumLineEdit, 0 ,1);
mainLayout->addWidget(ProgressType, 1, 0);
mainLayout->addWidget(comBox, 1, 1);
mainLayout->addWidget(progressBar, 2, 0, 1, 2);
mainLayout->addWidget(startBtn, 3, 1);
mainLayout->setMargin(15);
mainLayout->setSpacing(10);
connect(startBtn, SIGNAL(clicked()), this, SLOT(startProgress()));
}
Dialog::~Dialog()
{
}
void Dialog::startProgress()
{
bool ok;
int num = FileNumLineEdit->text().toInt(&ok);
if(comBox->currentIndex() == 0)
{
progressBar->setRange(0, num);
for(int i = 0; i <= num; ++i)
{
progressBar->setValue(i);
}
}
else if(comBox->currentIndex() == 1)
{
//创建一个进度对话框
QProgressDialog *progressDialog = new QProgressDialog(this);
qDebug() << "QProgressDialog display" << num;
QFont font("ZYSong1830", 12);
progressDialog->setFont(font);
progressDialog->setWindowModality(Qt::WindowModal);
progressDialog->setMinimumDuration(5);
progressDialog->setWindowTitle(tr("please Wait!"));
progressDialog->setLabelText(tr("Copying..."));
progressDialog->setCancelButtonText(tr("Cancel"));
progressDialog->setRange(0, num);
// progressDialog->show();
progressDialog->update();
for(int i = 0; i < num + 1; i++)
{
QThread::sleep(1);
progressDialog->setValue(i);
progressDialog->update();
if(progressDialog->wasCanceled())
{
return ;
}
}
}
}
实现效果
- progressbar效果
- progressdialog效果
在实际应用中,经常需要改变某个控件的颜色外观,如背景、文字颜色等。Qt提供的调色板类QPalette 专门用于管理对话框的的外观显示。
QPalette类相当于对话框或控件的调色板,它管理着控件或窗体的所有颜色信息。。每个窗口或控件都包含一个QPalette对象,在显示时,按照它的QPalette对象中对各部分各状态下的颜色的描述进行绘制。
示例实现
实现步骤
通过实例实现窗体调色板改变控件各部分颜色。
- 新建Qt Widget Application,项目名称命名为“Palette”,基类选择“QDialog”,类名命名为“Palette”,取消“创建界面”复选框,完成项目创建。
- palette.h
#ifndef PALETE_H
#define PALETE_H
#include <QDialog>
#include <QLabel>
#include <QTextEdit>
#include <QPushButton>
#include <QLineEdit>
#include <QComboBox>
class Palete : public QDialog
{
Q_OBJECT
public:
Palete(QWidget *parent = nullptr);
~Palete();
//完成窗体左半部分颜色选择区域
void createCtrlFrame();
//完成窗体右半部分的创建
void createContentFrame();
//完成颜色下拉列表框中插入颜色的创建
void fillColorList(QComboBox *);
private slots:
void showWindow();
void showWindowText();
void showButton();
void showButtonText();
void showBase();
private:
//颜色选择面板
QFrame *ctrlFrame;
QLabel *windowLabel;
QComboBox *windowComboBox;
QLabel *windowTextLabel;
QComboBox *windowTextComboBox;
QLabel *buttonLabel;
QComboBox *buttonComboBox;
QLabel *buttonTextLabel;
QComboBox *buttonTextComboBox;
QLabel *baseLabel;
QComboBox *baseTextComboBox;
QFrame *contentFrame;
QLabel *label1;
QComboBox *comboBox1;
QLabel *label2;
QLineEdit *textEdit2;
QTextEdit *textEdit;
QPushButton *OkBtn;
QPushButton *CancelBtn;
};
#endif // PALETE_H
- palette.cpp
#include "palete.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGridLayout>
Palete::Palete(QWidget *parent)
: QDialog(parent)
{
createCtrlFrame();
createContentFrame();
QHBoxLayout *mainLayout = new QHBoxLayout(this);
mainLayout->addWidget(ctrlFrame);
mainLayout->addWidget(contentFrame);
}
Palete::~Palete()
{
}
void Palete::createCtrlFrame()
{
//颜色选择面板
ctrlFrame = new QFrame;
windowLabel = new QLabel(tr("QPalette::Window:"));
windowComboBox = new QComboBox;
fillColorList(windowComboBox);
connect(windowComboBox, SIGNAL(activated(int)), this, SLOT(showWindow()));
windowTextLabel = new QLabel(tr("QPalette::WindowText:"));
windowTextComboBox = new QComboBox;
fillColorList(windowTextComboBox);
connect(windowTextComboBox, SIGNAL(activated(int)), this, SLOT(showWindowText()));
buttonLabel = new QLabel(tr("QPalette::button:"));
buttonComboBox = new QComboBox;
fillColorList(buttonComboBox);
connect(buttonComboBox, SIGNAL(activated(int)), this, SLOT(showButton()));
buttonTextLabel = new QLabel(tr("QPalette::buttonText:"));
buttonTextComboBox = new QComboBox;
fillColorList(buttonTextComboBox);
connect(buttonTextComboBox, SIGNAL(activated(int)), this, SLOT(showButtonText()));
baseLabel = new QLabel(tr("QPalette::Base:"));
baseTextComboBox = new QComboBox;
fillColorList(baseTextComboBox);
connect(baseTextComboBox, SIGNAL(activated(int)), this, SLOT(showBase()));
QGridLayout *mainLayout = new QGridLayout(ctrlFrame);
mainLayout->setSpacing(20);
mainLayout->addWidget(windowLabel, 0, 0);
mainLayout->addWidget(windowComboBox, 0, 1);
mainLayout->addWidget(windowTextLabel, 1, 0);
mainLayout->addWidget(windowTextComboBox, 1, 1);
mainLayout->addWidget(buttonLabel, 2, 0);
mainLayout->addWidget(buttonComboBox, 2, 1);
mainLayout->addWidget(buttonTextLabel, 3, 0);
mainLayout->addWidget(buttonTextComboBox, 3, 1);
mainLayout->addWidget(baseLabel, 4, 0);
mainLayout->addWidget(baseTextComboBox, 4, 1);
}
void Palete::createContentFrame()
{
contentFrame = new QFrame;
label1 = new QLabel(tr("请选择一个值:"));
comboBox1 = new QComboBox;
label2 = new QLabel(tr("请输入字符串:"));
textEdit2 = new QLineEdit;
textEdit = new QTextEdit;
QGridLayout *TopLayout = new QGridLayout;
TopLayout->addWidget(label1, 0, 0);
TopLayout->addWidget(comboBox1, 0, 1);
TopLayout->addWidget(label2, 1, 0);
TopLayout->addWidget(textEdit2, 1, 1);
TopLayout->addWidget(textEdit, 2, 0, 1, 2);
OkBtn = new QPushButton(tr("确认"));
CancelBtn = new QPushButton(tr("取消"));
QHBoxLayout *BottomLayout = new QHBoxLayout;
BottomLayout->addStretch(1);
BottomLayout->addWidget(OkBtn);
BottomLayout->addWidget(CancelBtn);
QVBoxLayout *mainLayout = new QVBoxLayout(contentFrame);
mainLayout->addLayout(TopLayout);
mainLayout->addLayout(BottomLayout);
}
void Palete::showWindow()
{
//获取当前选择的颜色值
QStringList colorList = QColor::colorNames();
QColor color = QColor(colorList[windowComboBox->currentIndex()]);
QPalette p = contentFrame->palette();
p.setColor(QPalette::Window, color);
//把修改后的调色板信息应用到contentframe窗体中,更新显示
contentFrame->setPalette(p);
contentFrame->update();
}
void Palete::showWindowText()
{
QStringList colorList = QColor::colorNames();
QColor color = colorList[windowTextComboBox->currentIndex()];
QPalette p = contentFrame->palette();
p.setColor(QPalette::WindowText, color);
contentFrame->setPalette(p);
contentFrame->update();
}
void Palete::showButton()
{
QStringList colorList = QColor::colorNames();
QColor color = QColor(colorList[buttonComboBox->currentIndex()]);
QPalette p = contentFrame->palette();
p.setColor(QPalette::Button, color);
contentFrame->setPalette(p);
contentFrame->update();
}
void Palete::showButtonText()
{
QStringList colorList = QColor::colorNames();
QColor color = QColor(colorList[buttonTextComboBox->currentIndex()]);
QPalette p = contentFrame->palette();
p.setColor(QPalette::ButtonText, color);
contentFrame->setPalette(p);
contentFrame->update();
}
void Palete::showBase()
{
QStringList colorList = QColor::colorNames();
QColor color = QColor(colorList[baseTextComboBox->currentIndex()]);
QPalette p = contentFrame->palette();
p.setColor(QPalette::Base, color);
contentFrame->setPalette(p);
contentFrame->update();
}
void Palete::fillColorList(QComboBox *comboBox)
{
QStringList colorlist = QColor::colorNames();
QString color;
foreach(color, colorlist)
{
QPixmap pix(QSize(70, 20));
pix.fill(QColor(color));
comboBox->addItem(QIcon(pix), NULL);
comboBox->setIconSize(QSize(70, 20));
comboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
}
}
实现界面显示
-
主界面显示
-
改变颜色
-
选择颜色
可扩展对话框的基本实现是理由setSizeConstraint(QLayout::SetFixedSize)方法,使对话框尺寸保持相对固定。其中,最关键的部分是以下两点:
- 在整个对话框的构造函数中调用以下语句。保证了对话框尺寸相对固定。对话框尺寸根据需要显示的控件进行拓展调整。
layout->setSizeConstraint(QLayout::SetFixedSize);
- 切换按钮的实现。整个窗体可扩展的工作都在此按钮连接的槽函数中完成。
示例实现
示例实现步骤
- 新建Qt Widgets Application项目,命名“ExtensionDlg”,基类选择“QDialog”,取消“创建界面”复选框。
- 实现 exitensiondlg.h 内容如下
#ifndef EXTENSIONDLG_H
#define EXTENSIONDLG_H
#include <QDialog>
class ExtensionDlg : public QDialog
{
Q_OBJECT
public:
ExtensionDlg(QWidget *parent = nullptr);
~ExtensionDlg();
private slots:
void showDetailInfo();
private:
void createBaseInfo();//实现基本对话框窗体部分
void createDetailInfo();//实现扩展窗体部分
QWidget *baseWidget; //基本对话窗体部分
QWidget *detailWidget; //扩展窗体部分
};
#endif // EXTENSIONDLG_H
- exitensiondlg.cpp内容如下:
#include "extensiondlg.h"
#include <QVBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QComboBox>
#include <QPushButton>
#include <QDialogButtonBox>
#include <QHBoxLayout>
ExtensionDlg::ExtensionDlg(QWidget *parent)
: QDialog(parent)
{
setWindowTitle(tr("Extension Dialog"));
createBaseInfo();
createDetailInfo();
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(baseWidget);
layout->addWidget(detailWidget);
layout->setSizeConstraint(QLayout::SetFixedSize);
layout->setSpacing(10);
}
ExtensionDlg::~ExtensionDlg()
{
}
void ExtensionDlg::createBaseInfo()
{
baseWidget = new QWidget;
QLabel *nameLabel = new QLabel(tr("姓名:"));
QLineEdit *nameLineEdit = new QLineEdit;
QLabel *sexLabel = new QLabel(tr("性别:"));
QComboBox *sexCombox = new QComboBox;
sexCombox->insertItem(0, tr("女"));
sexCombox->insertItem(1, tr("男"));
QGridLayout *leftlayout = new QGridLayout;
leftlayout->addWidget(nameLabel, 0, 0);
leftlayout->addWidget(nameLineEdit, 0, 1);
leftlayout->addWidget(sexLabel);
leftlayout->addWidget(sexCombox);
QPushButton *Okbtn = new QPushButton(tr("确定"));
QPushButton *Detailbtn = new QPushButton(tr("详细"));
QDialogButtonBox *btnBox = new QDialogButtonBox(Qt::Vertical);
btnBox->addButton(Okbtn, QDialogButtonBox::ActionRole);
btnBox->addButton(Detailbtn, QDialogButtonBox::ActionRole);
QHBoxLayout *mainLayout = new QHBoxLayout(baseWidget);
mainLayout->addLayout(leftlayout);
mainLayout->addWidget(btnBox);
connect(Detailbtn, SIGNAL(clicked()), this, SLOT(showDetailInfo()));
}
void ExtensionDlg::createDetailInfo()
{
detailWidget = new QWidget;
QLabel *ageLabel = new QLabel(tr("年龄:"));
QLineEdit *ageLineEdit = new QLineEdit;
ageLineEdit->setText(tr("30"));
QLabel *departmentLabel = new QLabel(tr("部门"));
QComboBox *departmentCombox = new QComboBox;
departmentCombox->addItem(tr("部门1"));
departmentCombox->addItem(tr("部门2"));
departmentCombox->addItem(tr("部门3"));
departmentCombox->addItem(tr("部门4"));
QLabel *emailLabel = new QLabel(tr("email:"));
QLineEdit *emailLineEdit = new QLineEdit;
QGridLayout *mainLayout = new QGridLayout(detailWidget);
mainLayout->addWidget(ageLabel, 0, 0);
mainLayout->addWidget(ageLineEdit, 0 ,1);
mainLayout->addWidget(departmentLabel, 1, 0);
mainLayout->addWidget(departmentCombox, 1, 1);
mainLayout->addWidget(emailLabel, 2, 0);
mainLayout->addWidget(emailLineEdit, 2, 1);
detailWidget->hide();
}
void ExtensionDlg::showDetailInfo()
{
if(detailWidget->isHidden())
detailWidget->show();
else
detailWidget->hide();
}
示例实现
- 主界面一:
- 扩展界面
如果需要在程序启动时优先显示一个启动或者进入程序的界面显示,可以使用Qt中提供的QSplashScreen类实现在程序启动过程中显示启动画面的功能。
示例
实现一个程序中添加一个启动画面作为启动界面的示例:
示例步骤
- 新建Qt Widgets Application,项目名称为“SplashSreen”,基类选择“QMainWindow”,类名命名为“MainWindow”,取消“创建界面”复选框的状态。
- mainWindow类中头文件中添加:
#ifndef MAINWIDGET_H
#define MAINWIDGET_H
#include <QWidget>
namespace Ui {
class mainWidget;
}
class mainWidget : public QWidget
{
Q_OBJECT
public:
explicit mainWidget(QWidget *parent = nullptr);
~mainWidget();
private:
Ui::mainWidget *ui;
};
#endif // MAINWIDGET_H
- mainWindow类中源文件中添加:
#include "mainwidget.h"
#include "ui_mainwidget.h"
mainWidget::mainWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::mainWidget)
{
setWindowTitle(tr("光子通讯编解码性能测试及分析软件"));
ui->setupUi(this);
setAutoFillBackground(true);
QPalette pal = this->palette();
pal.setBrush(backgroundRole(), QPixmap("22.jpg"));
setPalette(pal);
ui->textEdit->append(tr("单光子通讯发送服务端异常,请检查设置!"));
}
mainWidget::~mainWidget()
{
delete ui;
}
- 修改main.cpp主代码内容为:
#include "mainwidget.h"
#include <QApplication>
#include <QIcon>
#include <QPixmap>
#include <QSplashScreen>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QString strPath = QApplication::applicationDirPath();
strPath += "/31.jpg";
a.setWindowIcon(QIcon("31.jpg"));
QPixmap pixmap("23.png");
QSplashScreen splash(pixmap);
splash.resize(pixmap.size());
splash.show();
a.processEvents();
mainWidget w;
w.setWindowTitle(QObject::tr("main主界面"));
w.show();
return a.exec();
}