简述

通过前几节的自定义窗体的学习,我们可以很容易的写出一套属于自己风格的界面框架,通用于各种窗体,比如:QWidget、QDialog、QMainWindow。

大多数窗体的实现都是采用控件堆积来完成的,只要思路清晰,再复杂的界面实现起来都游刃有余。下面我来列举一个由QMessageBox扩展的提示框-根据其源码实现思路来实现!

效果

自定义提示框

实现

message_box.h

#ifndef MESSAGE_BOX
#define MESSAGE_BOX #include <QMessageBox>
#include <QDialogButtonBox>
#include <QGridLayout>
#include "custom_window.h" class QLabel; class MessageBox : public CustomWindow
{
Q_OBJECT public:
explicit MessageBox(QWidget *parent = 0, const QString &title = tr("Tip"), const QString &text = "",
QMessageBox::StandardButtons buttons = QMessageBox::Ok, QMessageBox::StandardButton defaultButton = QMessageBox::Ok);
~MessageBox();
QAbstractButton *clickedButton() const;
QMessageBox::StandardButton standardButton(QAbstractButton *button) const;
// 设置默认按钮
void setDefaultButton(QPushButton *button);
void setDefaultButton(QMessageBox::StandardButton button);
// 设置窗体标题
void setTitle(const QString &title);
// 设置提示信息
void setText(const QString &text);
// 设置窗体图标
void setIcon(const QString &icon);
// 添加控件-替换提示信息所在的QLabel
void addWidget(QWidget *pWidget); protected:
// 多语言翻译
void changeEvent(QEvent *event); private slots:
void onButtonClicked(QAbstractButton *button); private:
void translateUI();
int execReturnCode(QAbstractButton *button); private:
QLabel *m_pIconLabel;
QLabel *m_pLabel;
QGridLayout *m_pGridLayout;
QDialogButtonBox *m_pButtonBox;
QAbstractButton *m_pClickedButton;
QAbstractButton *m_pDefaultButton;
};

message_box.cpp

#include <QLabel>
#include <QPushButton>
#include <QMessageBox>
#include <QCheckBox>
#include <QHBoxLayout>
#include <QEvent>
#include <QApplication>
#include "message_box.h" MessageBox::MessageBox(QWidget *parent, const QString &title, const QString &text,
QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
: CustomWindow(parent)
{
setWindowIcon(QIcon(":/Images/logo"));
setWindowTitle(title);
setMinimumSize(300, 130);
setMinimizeVisible(false);
setMaximizeVisible(false);
setWidgetResizable(false); m_pButtonBox = new QDialogButtonBox(this);
m_pButtonBox->setStandardButtons(QDialogButtonBox::StandardButtons(int(buttons)));
setDefaultButton(defaultButton); QPushButton *pYesButton = m_pButtonBox->button(QDialogButtonBox::Yes);
if (pYesButton != NULL)
{
pYesButton->setObjectName("blueButton");
pYesButton->setStyle(QApplication::style());
} m_pIconLabel = new QLabel(this);
m_pLabel = new QLabel(this); QPixmap pixmap(":/Images/information");
m_pIconLabel->setPixmap(pixmap);
m_pIconLabel->setFixedSize(35, 35);
m_pIconLabel->setScaledContents(true); m_pLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
m_pLabel->setObjectName("whiteLabel");
m_pLabel->setOpenExternalLinks(true);
m_pLabel->setText(text); m_pGridLayout = new QGridLayout();
m_pGridLayout->addWidget(m_pIconLabel, 0, 0, 2, 1, Qt::AlignTop);
m_pGridLayout->addWidget(m_pLabel, 0, 1, 2, 1);
m_pGridLayout->addWidget(m_pButtonBox, m_pGridLayout->rowCount(), 0, 1, m_pGridLayout->columnCount());
m_pGridLayout->setSizeConstraint(QLayout::SetNoConstraint);
m_pGridLayout->setHorizontalSpacing(10);
m_pGridLayout->setVerticalSpacing(10);
m_pGridLayout->setContentsMargins(10, 10, 10, 10);
m_pLayout->addLayout(m_pGridLayout); translateUI(); connect(m_pButtonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(onButtonClicked(QAbstractButton*)));
} MessageBox::~MessageBox()
{ } void MessageBox::changeEvent(QEvent *event)
{
switch (event->type())
{
case QEvent::LanguageChange:
translateUI();
break;
default:
CustomWindow::changeEvent(event);
}
} void MessageBox::translateUI()
{
QPushButton *pYesButton = m_pButtonBox->button(QDialogButtonBox::Yes);
if (pYesButton != NULL)
pYesButton->setText(tr("Yes")); QPushButton *pNoButton = m_pButtonBox->button(QDialogButtonBox::No);
if (pNoButton != NULL)
pNoButton->setText(tr("No")); QPushButton *pOkButton = m_pButtonBox->button(QDialogButtonBox::Ok);
if (pOkButton != NULL)
pOkButton->setText(tr("Ok")); QPushButton *pCancelButton = m_pButtonBox->button(QDialogButtonBox::Cancel);
if (pCancelButton != NULL)
pCancelButton->setText(tr("Cancel"));
} QMessageBox::StandardButton MessageBox::standardButton(QAbstractButton *button) const
{
return (QMessageBox::StandardButton)m_pButtonBox->standardButton(button);
} QAbstractButton *MessageBox::clickedButton() const
{
return m_pClickedButton;
} int MessageBox::execReturnCode(QAbstractButton *button)
{
int nResult = m_pButtonBox->standardButton(button);
return nResult;
} void MessageBox::onButtonClicked(QAbstractButton *button)
{
m_pClickedButton = button;
done(execReturnCode(button));
} void MessageBox::setDefaultButton(QPushButton *button)
{
if (!m_pButtonBox->buttons().contains(button))
return;
m_pDefaultButton = button;
button->setDefault(true);
button->setFocus();
} void MessageBox::setDefaultButton(QMessageBox::StandardButton button)
{
setDefaultButton(m_pButtonBox->button(QDialogButtonBox::StandardButton(button)));
} void MessageBox::setTitle(const QString &title)
{
setWindowTitle(title);
} void MessageBox::setText(const QString &text)
{
m_pLabel->setText(text);
} void MessageBox::setIcon(const QString &icon)
{
m_pIconLabel->setPixmap(QPixmap(icon));
} void MessageBox::addWidget(QWidget *pWidget)
{
m_pLabel->hide();
m_pGridLayout->addWidget(pWidget, 0, 1, 2, 1);
}

接口说明

  • CustomWindow

    主要对界面的无边框可拖动进行了封装

  • MessageBox

    整体界面布局及事件处理参考了QMessageBox源码,接口包含:设置标题、提示信息、默认按钮及事件触发等操作。

二次封装

针对于各种提示框,我们可以再次进行封装,将常用的提取出来,作为全局函数来使用。

QMessageBox::StandardButton showInformation(QWidget *parent, const QString &title,
const QString &text, QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton)
{
MessageBox msgBox(parent, title, text, buttons, defaultButton);
msgBox.setIcon(":/Images/information");
if (msgBox.exec() == -1)
return QMessageBox::Cancel;
return msgBox.standardButton(msgBox.clickedButton());
} QMessageBox::StandardButton showError(QWidget *parent, const QString &title,
const QString &text, QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton)
{
MessageBox msgBox(parent, title, text, buttons, defaultButton);
msgBox.setIcon(":/Images/error");
if (msgBox.exec() == -1)
return QMessageBox::Cancel;
return msgBox.standardButton(msgBox.clickedButton());
} QMessageBox::StandardButton showSuccess(QWidget *parent, const QString &title,
const QString &text, QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton)
{
MessageBox msgBox(parent, title, text, buttons, defaultButton);
msgBox.setIcon(":/Images/success");
if (msgBox.exec() == -1)
return QMessageBox::Cancel;
return msgBox.standardButton(msgBox.clickedButton());
} QMessageBox::StandardButton showQuestion(QWidget *parent, const QString &title,
const QString &text, QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton)
{
MessageBox msgBox(parent, title, text, buttons, defaultButton);
msgBox.setIcon(":/Images/question");
if (msgBox.exec() == -1)
return QMessageBox::Cancel;
return msgBox.standardButton(msgBox.clickedButton());
} QMessageBox::StandardButton showWarning(QWidget *parent, const QString &title,
const QString &text, QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton)
{
MessageBox msgBox(parent, title, text, buttons, defaultButton);
msgBox.setIcon(":/images/warning");
if (msgBox.exec() == -1)
return QMessageBox::Cancel;
return msgBox.standardButton(msgBox.clickedButton());
} QMessageBox::StandardButton showCritical(QWidget *parent, const QString &title,
const QString &text, QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton)
{
MessageBox msgBox(parent, title, text, buttons, defaultButton);
msgBox.setIcon(":/Images/warning");
if (msgBox.exec() == -1)
return QMessageBox::Cancel;
return msgBox.standardButton(msgBox.clickedButton());
} QMessageBox::StandardButton showCheckBoxQuestion(QWidget *parent, const QString &title,
const QString &text, QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton)
{
MessageBox msgBox(parent, title, text, buttons, defaultButton);
msgBox.setIcon(":/Images/question"); QCheckBox *pCheckBox = new QCheckBox(&msgBox);
pCheckBox->setText(text);
msgBox.addWidget(pCheckBox);
if (msgBox.exec() == -1)
return QMessageBox::Cancel; QMessageBox::StandardButton standardButton = msgBox.standardButton(msgBox.clickedButton());
if (standardButton == QMessageBox::Yes)
{
return pCheckBox->isChecked() ? QMessageBox::Yes : QMessageBox::No;
}
return QMessageBox::Cancel;
}

使用方式

showInformation(this, QStringLiteral("提示"), QStringLiteral("这是一个普通的提示框-Information!"));
showQuestion(this, QStringLiteral("提示"), QStringLiteral("这是一个普通的提示框-Question!"));
showSuccess(this, QStringLiteral("提示"), QStringLiteral("这是一个普通的提示框-Success!"));
showError(this, QStringLiteral("提示"), QStringLiteral("这是一个普通的提示框-Error!"));

源码学习

其实Qt中有很多自带的比较好的效果,里面用了很好的实现方式,建议安装的时候把源码download下来,随时可以研究并学习。例如:D:\Qt\Qt5.5.1\5.5\Src\qtbase\src\widgets\dialogs下面包含了所有关于dialog的实现-QProgressDialog、QMessageBox、QFileDialog。。。

Qt之自定义界面(QMessageBox)的更多相关文章

  1. 【Qt】Qt之自定义界面(QMessageBox)【转】

    简述 通过前几节的自定义窗体的学习,我们可以很容易的写出一套属于自己风格的界面框架,通用于各种窗体,比如:QWidget.QDialog.QMainWindow. 大多数窗体的实现都是采用控件堆积来完 ...

  2. Qt学习笔记 QMessageBox

    Qt的几种MessageBox 1.Infomation类型 QMessageBox::information(this,tr("hello"),tr("title&qu ...

  3. 【Qt】Qt之自定义界面(窗体缩放-跨平台终极版)【转】

    简述 通过上一节内容,我们实现了窗体的缩放,功能很不错,但是很遗憾-不支持跨平台!如果对于多平台来说,这是一个硬伤,所以,我们急需要一个能够支持跨平台的实现方案. 在网上看到过很多不同的实现方式,多多 ...

  4. 【Qt】Qt之自定义界面(添加自定义标题栏)【转】

    简述 通过上节内容,我们实现了自定义窗体的移动,但是我们缺少一个标题栏来显示窗体的图标.标题,以及控制窗体最小化.最大化.关闭的按钮. 自定义标题栏后,所有的控件我们都可以定制,比如:在标题栏中添加换 ...

  5. 【Qt】Qt之自定义界面(实现无边框、可移动)【转】

    简述 UI设计是指对软件的人机交互.操作逻辑.界面美观的整体设计.好的UI设计不仅是让软件变得有个性.有品位,还要让软件的操作变得舒适简单.自由,充分体现软件的定位和特点. 爱美之心人皆有之.其实软件 ...

  6. Qt之自定义界面(窗体缩放-跨平台终极版)

    简述 通过上一节内容,我们实现了窗体的缩放,功能很不错,但是很遗憾-不支持跨平台!如果对于多平台来说,这是一个硬伤,所以,我们急需要一个能够支持跨平台的实现方案. 在网上看到过很多不同的实现方式,多多 ...

  7. Qt之自定义界面(窗体缩放)

    简述 通过前两节内容,我们实现了自定义窗体的移动,以及自定义标题栏-用来显示窗体的图标.标题,以及控制窗体最小化.最大化.关闭. 在这之后,我们还缺少窗体的缩放-当鼠标移动到窗体的边框-左.上.右.下 ...

  8. Qt之自定义界面(添加自定义标题栏)

    简述 通过上节内容,我们实现了自定义窗体的移动,但是我们缺少一个标题栏来显示窗体的图标.标题,以及控制窗体最小化.最大化.关闭的按钮. 自定义标题栏后,所有的控件我们都可以定制,比如:在标题栏中添加换 ...

  9. Qt之自定义界面(实现无边框、可移动)

    简述 UI设计是指对软件的人机交互.操作逻辑.界面美观的整体设计.好的UI设计不仅是让软件变得有个性.有品位,还要让软件的操作变得舒适简单.自由,充分体现软件的定位和特点. 爱美之心人皆有之.其实软件 ...

随机推荐

  1. BAT CMD 批处理文件脚本 -2

    http://checheng1988.blog.51cto.com/4725808/1090733 在很多windows程序中会见到很多用扩展名为.bat和.cmd结尾的文件,那么这些文件能干什么呢 ...

  2. python爬取某些网站出错的解决办法

    用urllib2.urlopen方法打开糗事百科的网站,http://www.qiushibaike.com/,发现会失败,网上百度,说可能是服务器端对爬虫做了屏蔽,需要伪装header头部信息,下面 ...

  3. 【BZOJ】【2693】JZPTAB

    莫比乌斯反演 PoPoQQQ讲义第5题,是BZOJ 2154的升级版(多次询问) 题解:http://blog.csdn.net/popoqqq/article/details/42078725 WA ...

  4. 清除HTML中的特殊字符

    /// <summary>        /// 清楚HTML中的特殊字符        /// </summary>        /// <param name=&q ...

  5. PHP读取xml方法讲解

    一,什么是xml,xml有什么用途 XML(Extensible Markup Language)即可扩展标记语言,它与HTML一样,都是SGML(Standard Generalized Marku ...

  6. How to define Servlet filter order of execution using annotations

    If we define Servlet filters in web.xml, then the order of execution of the filters will be the same ...

  7. [转] ADO.NET实体框架引发争论

    转自:http://developer.51cto.com/art/200811/76356.htm 2008-11-11 14:00 朱永光译 infoq 我要评论(0) 一个在ADO.NET实体框 ...

  8. django如何用orm增加manytomany关系字段(自定义表名)

    不自定义表名的,网上有现成的,但如果自定义之后,则要变通一下了. app_insert = App.objects.get(name=app_name) site_insert = Site.obje ...

  9. String类的使用 Part2

    StringBuilder 类的使用 属性: namespace StringBuilderTest { class Program { static void Main(string[] args) ...

  10. lintcode : 平衡二叉树

    题目 平衡二叉树 给定一个二叉树,确定它是高度平衡的.对于这个问题,一棵高度平衡的二叉树的定义是:一棵二叉树中每个节点的两个子树的深度相差不会超过1. 样例 给出二叉树 A={3,9,20,#,#,1 ...