进度条

通常在处理长时间任务时需要提供进度条用于显示时间。
进度条对话框的使用方法有两种,即模态方式与非模态方式。
模态方式的使用比较简单方便,但必须使用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效果
    Qt5——基本对话框(2)_#endif
  • progressdialog效果
    Qt5——基本对话框(2)_#endif_02
调色板

在实际应用中,经常需要改变某个控件的颜色外观,如背景、文字颜色等。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);
    }
}

实现界面显示

  • 主界面显示
    Qt5——基本对话框(2)_#endif_03

  • 改变颜色
    Qt5——基本对话框(2)_ico_04

  • 选择颜色
    Qt5——基本对话框(2)_#include_05

扩展对话框

可扩展对话框的基本实现是理由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();
}

示例实现

  • 主界面一:
    Qt5——基本对话框(2)_#include_06
  • 扩展界面

Qt5——基本对话框(2)_进度条_07

程序启动画面(QSplashScreen)

如果需要在程序启动时优先显示一个启动或者进入程序的界面显示,可以使用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();
}


示例实现

Qt5——基本对话框(2)_#include_08