Qt 实现带阴影 无边框的QMessageBox
Qt 实现带阴影的QMessagebox
在实际项目里面使用到了QMessageBox做一个弹窗,最开始是样式不是需要的样式,就去找了一下QMessageBox的样式表,一般来说可以使用findChild()来找到这个控件中的一切子控件,Qt的许多控件都是由一些其他的控件组合在一起。
下面这个函数是来自博主公孙二狗
void MainWidget::dumpStructure(const QObject *obj, int spaceCount) {
qDebug() << QString("%1%2 : %3")
.arg("", spaceCount)
.arg(obj->metaObject()->className())
.arg(obj->objectName());
QObjectList list = obj->children();
foreach (QObject * child, list) {
dumpStructure(child, spaceCount + 4);
}
}
就是一个递归函数,来一直遍历子控件的内容,下面是输出的结果
"QMessageBox : "
" QLabel : qt_msgboxex_icon_label"
" QGridLayout : "
" QLabel : qt_msgbox_label"
" QDialogButtonBox : qt_msgbox_buttonbox"
" QHBoxLayout : "
这表明,QMessageBox里面有QLable -> qt_msgboxex_icon_label这个是指框里的图标、QLabel -> qt_msgbox_label这个就是里面文字,QDialogButtonBox -> qt_msgbox_buttonbox这个就是按钮,例如下图:

下图是我设置的样式表,这样式表部分参考自QSS 自定义QMessageBox
/* =============================================== */
/* QMessageBox */
/* =============================================== */
/*设置背景*/
QMessageBox
{
background-color: rgba(51, 153, 251, 1);
border-radius: 3px;
width: 240px;
height: 180px;
}
/*设置QMessageBox的文字内容*/
QMessageBox QLabel#qt_msgbox_label { /* textLabel */
color: rgba(255, 255, 255, 1);
background-color: transparent;
min-width: 240px; /* textLabel设置最小宽度可以相应的改变QMessageBox的最小宽度 */
min-height: 80px; /* textLabel和iconLabel高度保持一致 */
}
/*设置图标*/
QMessageBox QLabel#qt_msgboxex_icon_label { /* iconLabel */
width: 80px;
height: 80px; /* textLabel和iconLabel高度保持一致 */
}
/*设置按钮样式*/
QMessageBox QPushButton
{
background-color: rgba(51, 153, 251, 1);
width: 50px;
height: 20px;
color: rgba(0, 0, 0, 1);
font: 10pt "Microsoft YaHei";
border-style: inset;
border-color: rgba(0, 74, 169, 1);
border-width: 1;
}
这是效果图:

但是你会发现一个问题,就是这个对话框的标题的背景什么的并不可以修改,这个标题栏的样式是跟随系统的。所以这个时候就需要自己实现一个对话框来解决这些问题。下面是我设计的对话框,参考了大佬一去二三里的博客。
#ifndef SHADOWMESSAGEBOX_H
#define SHADOWMESSAGEBOX_H
#include <QWidget>
#include <QLabel>
#include <QIcon>
#include <QHBoxLayout>
#include <QPushButton>
#include <QGraphicsDropShadowEffect>
#include "titlebar.h"
class ShadowMessageBox : public QWidget
{
Q_OBJECT
public:
enum Icon {
// keep this in sync with QMessageDialogOptions::Icon
NoIcon = 0,
Information = 1,
Warning = 2,
Critical = 3,
Question = 4
};
ShadowMessageBox(QWidget * parent);
ShadowMessageBox(QWidget * parent, const QString &title, const QString &text, ShadowMessageBox::Icon icon=Information);
static void information(QWidget * parent, const QString &title, const QString &text);
static void critical(QWidget * parent, const QString &title, const QString &text);
private:
QWidget * m_widg;
TitleBar * m_pTitleBar;
QVBoxLayout *m_pLayout;
QLabel * m_msgIcon;
QLabel * m_msgText;
QHBoxLayout * m_hlabLayout;
QHBoxLayout * m_hbtnLayout;
QSpacerItem * m_horizontalSpacer;
QSpacerItem * m_horizontalSpacer_2;
QPushButton * m_btnOK;
QHBoxLayout * m_hpLayout;
QGraphicsDropShadowEffect *m_pEffect;
// QMap<ShadowMessageBox::Icon, QString> m_ico{{NoIcon, ""}};
};
#endif // SHADOWMESSAGEBOX_H
#include "shadowmessagebox.h"
ShadowMessageBox::ShadowMessageBox(QWidget *parent)
:QWidget(parent)
{
this->setAttribute(Qt::WA_TranslucentBackground);
this->setAttribute(Qt::WA_DeleteOnClose);
this->setWindowFlags(this->windowFlags()|Qt::WindowStaysOnTopHint|Qt::FramelessWindowHint |Qt::Dialog);
this->setWindowModality(Qt::WindowModal);
this->setVisible(true);
m_widg = new QWidget(this);
m_pTitleBar = new TitleBar(m_widg);
m_widg->installEventFilter(m_pTitleBar);
m_widg->setWindowTitle("QMessageBox");
m_widg->setWindowIcon(QIcon("D:\\1.ico"));
QPalette pal(palette());
pal.setColor(QPalette::Background, QColor(51, 153, 251, 255));
m_widg->setAutoFillBackground(true);
m_widg->setPalette(pal);
m_pLayout = new QVBoxLayout(m_widg);
m_pLayout->addWidget(m_pTitleBar);
m_pLayout->addStretch();
m_pLayout->setSpacing(0);
m_pLayout->setContentsMargins(0, 0, 0, 5);
m_widg->setLayout(m_pLayout);
m_msgIcon = new QLabel(m_widg);
m_msgIcon->setFixedSize(48,48);
m_msgIcon->setPixmap(QPixmap("D:/images/CG.png", "png"));
m_msgText = new QLabel(m_widg);
m_msgText->setStyleSheet("font: 20pt \"Microsoft YaHei\";color: white;");
m_msgText->setText("导出成功");
m_hlabLayout = new QHBoxLayout();
m_hlabLayout->addWidget(m_msgIcon);
m_hlabLayout->addWidget(m_msgText);
m_hlabLayout->setContentsMargins(5,0,5,0);
m_pLayout->addLayout(m_hlabLayout);
m_hbtnLayout= new QHBoxLayout();
m_horizontalSpacer= new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Expanding);
m_hbtnLayout->addItem(m_horizontalSpacer);
m_btnOK = new QPushButton(m_widg);
m_btnOK->setFixedSize(72,25);
m_btnOK->setText("OK");
m_btnOK->setStyleSheet("border:1px solid rgba(0, 74, 169, 1);font: 10px \"Microsoft YaHei\";color: rgba(0, 0, 0, 1)");
m_hbtnLayout->addWidget(m_btnOK);
m_horizontalSpacer_2= new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Expanding);
m_hbtnLayout->addItem(m_horizontalSpacer_2);
connect(m_btnOK, &QPushButton::clicked, this, &QWidget::close);
m_pLayout->addLayout(m_hbtnLayout);
m_hpLayout = new QHBoxLayout(this);
m_hpLayout->addWidget(m_widg);
m_hpLayout->setContentsMargins(20, 20, 20, 20);
m_pEffect = new QGraphicsDropShadowEffect(m_widg);
m_pEffect->setOffset(0, 0);
m_pEffect->setColor(QColor(QStringLiteral("black")));
m_pEffect->setBlurRadius(30);
m_widg->setGraphicsEffect(m_pEffect);
}
ShadowMessageBox::ShadowMessageBox(QWidget *parent, const QString &title, const QString &text , ShadowMessageBox::Icon icon)
:QWidget(parent)
{
this->setAttribute(Qt::WA_TranslucentBackground);
this->setAttribute(Qt::WA_DeleteOnClose);
this->setWindowFlags(this->windowFlags()|Qt::WindowStaysOnTopHint|Qt::FramelessWindowHint |Qt::Dialog);
this->setWindowModality(Qt::WindowModal);
this->setVisible(true);
m_widg = new QWidget(this);
m_pTitleBar = new TitleBar(m_widg);
m_widg->installEventFilter(m_pTitleBar);
m_widg->setWindowTitle(title);
m_widg->setWindowIcon(this->windowIcon());
QPalette pal(palette());
pal.setColor(QPalette::Background, QColor(51, 153, 251, 255));
m_widg->setAutoFillBackground(true);
m_widg->setPalette(pal);
m_pLayout = new QVBoxLayout(m_widg);
m_pLayout->addWidget(m_pTitleBar);
m_pLayout->addStretch();
m_pLayout->setSpacing(0);
m_pLayout->setContentsMargins(0, 0, 0, 5);
m_widg->setLayout(m_pLayout);
m_msgIcon = new QLabel(m_widg);
m_msgIcon->setFixedSize(48,48);
if (icon == ShadowMessageBox::Icon::Information) {
m_msgIcon->setPixmap(QPixmap(":/images/images/TS.png"));
}
else if (icon == ShadowMessageBox::Icon::Critical) {
m_msgIcon->setPixmap(QPixmap(":/images/images/CW.png"));
}
m_msgText = new QLabel(m_widg);
m_msgText->setStyleSheet("font: 20pt \"Microsoft YaHei\";color: white;");
m_msgText->setText(text);
m_hlabLayout = new QHBoxLayout();
m_hlabLayout->addWidget(m_msgIcon);
m_hlabLayout->addWidget(m_msgText);
m_hlabLayout->setContentsMargins(5,0,5,0);
m_pLayout->addLayout(m_hlabLayout);
m_hbtnLayout= new QHBoxLayout();
m_horizontalSpacer= new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Expanding);
m_hbtnLayout->addItem(m_horizontalSpacer);
m_btnOK = new QPushButton(m_widg);
m_btnOK->setFixedSize(72,25);
m_btnOK->setText("OK");
m_btnOK->setStyleSheet("border:1px solid rgba(0, 74, 169, 1);font: 10px \"Microsoft YaHei\";color: rgba(0, 0, 0, 1)");
m_hbtnLayout->addWidget(m_btnOK);
m_horizontalSpacer_2= new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Expanding);
m_hbtnLayout->addItem(m_horizontalSpacer_2);
connect(m_btnOK, &QPushButton::clicked, this, &QWidget::close);
m_pLayout->addLayout(m_hbtnLayout);
m_hpLayout = new QHBoxLayout(this);
m_hpLayout->addWidget(m_widg);
m_hpLayout->setContentsMargins(20, 20, 20, 20);
m_pEffect = new QGraphicsDropShadowEffect(m_widg);
m_pEffect->setOffset(0, 0);
m_pEffect->setColor(QColor(QStringLiteral("black")));
m_pEffect->setBlurRadius(30);
m_widg->setGraphicsEffect(m_pEffect);
}
void ShadowMessageBox::information(QWidget *parent, const QString &title, const QString &text)
{
ShadowMessageBox * msgBox = new ShadowMessageBox(parent , title, text, ShadowMessageBox::Icon::Information);
}
void ShadowMessageBox::critical(QWidget *parent, const QString &title, const QString &text)
{
ShadowMessageBox * msgBox = new ShadowMessageBox(parent , title, text, ShadowMessageBox::Icon::Critical);
}
调用方法为:
ShadowMessageBox::information(this, "提示", "提示");
// 这个this必须指定
关于阴影的部分,我也是折腾了好一会,具体结构图如下:

本来的是想直接放在MainWindow下的,但是这个要设置窗口背景透明,这样就会导致其他的样式不对,所以就依附在一个新创建的widget上。代码如下:
// 首先你要把这个最外层的widget设置成透明
this->setAttribute(Qt::WA_TranslucentBackground);
this->setAttribute(Qt::WA_DeleteOnClose);
this->setWindowFlags(this->windowFlags()|Qt::WindowStaysOnTopHint|Qt::FramelessWindowHint |Qt::Dialog);
this->setWindowModality(Qt::WindowModal);
this->setVisible(true);
// 然后要设置一个布局管理器,来设置间距。以达到显示阴影的目的
m_hpLayout = new QHBoxLayout(this);
m_hpLayout->addWidget(m_widg);
m_hpLayout->setContentsMargins(20, 20, 20, 20); // 这里是设置上下左右的阴影宽度
// 这里就是给带标题栏的那个widget添加阴影
m_pEffect = new QGraphicsDropShadowEffect(m_widg);
m_pEffect->setOffset(0, 0);
m_pEffect->setColor(QColor(QStringLiteral("black")));
m_pEffect->setBlurRadius(30); // 设置阴影圆角
m_widg->setGraphicsEffect(m_pEffect);
效果图如下:

这个阴影部分可以参考以下博客
标题栏
阴影
阴影
九宫格缩放图片原理
阴影(附带九宫格)
以上TitleBar这个类,是博主一去、二三里大神的博文中的一个标题栏的类,请移步Qt 之自定义界面(添加自定义标题栏),然后还参考了Qt官方的QMessageBox的设计,写出来了。本人代码水平不是特别的好,还有许多没有完善,里面应该有挺多的问题,只是给大家提供一个思路,烦请大家多多指正。
Qt 实现带阴影 无边框的QMessageBox的更多相关文章
- Qt 创建圆角、无边框、有阴影、可拖动的窗口 good
程序窗口的边框,标题栏等是系统管理的,Qt 不能对其进行定制,为了实现定制的边框.标题栏.关闭按钮等,需要把系统默认的边框.标题栏去掉,然后使用 Widget 来模拟它们.这里介绍使用 QSS + Q ...
- Qt的三套无边框窗体的方案:可按比例拖拽窗体大小的无边框窗口和几个常见的无边框实例
一.可按比例拖拽窗体大小的无边框窗口 前几天接到一个需求,就是视频广播的窗体画面要可以拖拽,修改成了可以拖拽全屏的窗口之后,又有一个问题:视频画面也被拉伸了. 由于视频画面是有比例的,所以我们最好也能 ...
- qt动态库实现无边框窗体的消息处理 nativeEvent的使用
需求: 在动态库中创建一个窗口句柄,可以给外部调用,库的调用者,通过这个句柄发送消息到底层库,库里面可以实现对消息的处理 m_FHandle=AllocateHWnd(WndProcDllMsg); ...
- Qt QQuickView设置成无边框无标题栏
#include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQuickView> ...
- Devexpres下窗体带阴影的边框效果
public partial class Form1 : DevExpress.XtraEditors.XtraForm { public Form1() { InitializeComponent( ...
- Qt 无边框窗体改变大小 完美实现(全部自己实现)
近期,做项目用到无边框窗体,令人蛋疼的是无边框窗体大小的改变要像右边框那样,上下左右四周,而且要流畅. 网上也找了些代码,发现居然还要连接到windows事件,这显然不合常理,后来自己新建了demo, ...
- Qt 无边框窗体改变大小 完美实现
近期,做项目用到无边框窗体,令人蛋疼的是无边框窗体大小的改变要像右边框那样,上下左右四周,而且要流畅. 网上也找了些代码,发现居然还要连接到windows事件,这显然不合常理,后来自己新建了demo, ...
- 让Qt的无边框窗口支持拖拽、Aero Snap、窗口阴影等特性
环境:Desktop Qt 5.4.1 MSVC2013 32bit 需要的库:dwmapi.lib .user32.lib 需要头文件:<dwmapi.h> .<windowsx. ...
- QT模态对话框用法(在UI文件中设置Widget背景图,这个图是一个带阴影边框的图片——酷)
QT弹出模态对话框做法: 1.新建UI文件时,一定要选择基类是QDialog的,我的选择是:Dialog without Buttons(),如下图: 2.然后在使用的时候: MyDialog dlg ...
- Qt自带的阴影类、跨线程问题汇总、hover相关、全屏轮子,一些思考。
一点思考:故事的结局重不重要? 我语文不好,但是我数学不好. 我数学不好,但是我英语不好. 我英语不好,但是我物理不好. 我物理不好,但是我化学不好. 我化学不好,但是我历史不好. 我历史不好,但是我 ...
随机推荐
- 代码依赖包安全漏洞检测神器 —— Dependency Check
目前各个企业对于应用的安全越来越重视,而解决应用漏洞的本质是从代码安全抓起.通常关于代码的安全问题有两类:代码本身的安全问题和代码依赖包存在的安全问题.对于代码本身的安全问题,我们可以通过静态代码分析 ...
- 关于Java的UUID
UUID或者UNID或者UID,是一个统一唯一标识,可以用来标记文档.数据或其它需要唯一标识的东西.Java 5.0内置UUID的实现,见java.util.UUID. 下面代码是找到的2种实现方式, ...
- 【深度剖析】自主可控的全国产方案,基于龙芯LS2K1000LA-i!
龙芯LS2K1000LA-i产品简介 LS2K1000LA-i是龙芯双核LoongArch LA264自主架构处理器.创龙科技基于LS2K1000LA-i设计的工业核心板(SOM-TL2K1000)板 ...
- Exadata X6支持的最新image和19c数据库版本?
如题,有客户咨询这个问题:Exadata X6支持的最新image和19c数据库版本? 直观感觉,看到X6这个型号就觉得是很老的机器了,毕竟现在最新都X10M了. 首先,去查MOS文档: Exadat ...
- 优化博客Ⅱ-CDN加速
CDN加速 自从有了第一次博客优化经验,我就越发对优化感兴趣了嘿嘿(✧∇✧). 看着博客首页打开时长为1200ms左右,我又开始琢磨有什么办法能再给网站提提速,让访问时间降低到1000ms以下,这时候 ...
- 展锐SE8451E 开启硬件流控
Dear Customer: 如电话沟通,若将uart0配置成3M波特率,需进行如下更改: 1.时钟源更改为96M/sprdroid10_trunk_19c_rls1/bsp/kernel/ker ...
- nginx升级与版本回退
ginx官网下载安装包http://nginx.org/en/download.html 查看nginx文件或目录find / -name nginx 2>/dev/null 查看已安装的 Ng ...
- MAC 使用问题汇总
1. 在.zshrc中添加的环境变量不起作用 Answer: 需要把/etc/zshrc文件复制到 ~, 并命名为.zshrc,然后设置环境变量即可:
- Nginx-总结列表
Nginx配置详解 Nginx实现前后端分离,反向代理.负载均衡 Nginx 专为性能优化而开发,性能是其最重要的考量,实现上非常注重效率 .它支持内核 Poll 模型,能经受高负载的考验,有报告表明 ...
- MVCC基本原理
在介绍MVCC概念之前,我们先来想一下数据库系统里的一个问题:假设有多个用户同时读写数据库里的一行记录,那么怎么保证数据的一致性呢?一个基本的解决方法是对这一行记录加上一把锁,将不同用户对同一行记录的 ...