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相关、全屏轮子,一些思考。
一点思考:故事的结局重不重要? 我语文不好,但是我数学不好. 我数学不好,但是我英语不好. 我英语不好,但是我物理不好. 我物理不好,但是我化学不好. 我化学不好,但是我历史不好. 我历史不好,但是我 ...
随机推荐
- 微服务之调用链(Feign+SpringCloud)
终于到了我们的重点,微服务了. 与使用OkHttp3来实现的客户端类似,Feign接口本来也就是一个Http调用,依然可以使用Http头传值的方式,将 Trace 往下传. 本文更多的是关于 Spri ...
- MySQL said: Authentication plugin 'caching_sha2_password' cannot be loaded
OUTLINE问题描述解决方案问题描述在mac下,用sequel pro连接数据库,出现以下问题: MySQL said: Authentication plugin 'caching_sha2_pa ...
- 记一次单元测试问题com.sun.crypto.provider.HmacSHA1 cannot be cast to javax.crypto.MacSpi
在用单元测试Junit测试部门的SDK时,有个md5鉴权步骤,出现了java.lang.ClassCastException: com.sun.crypto.provider.HmacSHA1 can ...
- Qt音视频开发40-ffmpeg采集桌面并录制
一.前言 之前用ffmpeg打通了各种视频文件和视频流以及本地摄像头设备的采集,近期有个客户需求要求将整个桌面屏幕采集下来,并可以录制保存成MP4文件,以前也遇到过类似的需求,由于没有搞过,也没有精力 ...
- 什么是 单点登录SSO?SSO工作原理
记住多个用户名和密码来访问不同网站和应用程序很麻烦.单点登录 (SSO) 允许用户使用一组凭证访问多个资源,从而消除了对多个用户 ID 和密码的需求. 没有 SSO 的世界 在没有 SSO 的情况下, ...
- elementPlus 问题总结
第一次搞,遇上很多弱智问题,记录一下 安装elementPlus $ npm install element-plus --save 全局引入 import ElementPlus from 'ele ...
- [转]fatal: remote error: The unauthenticated git protocol on port 9418 is no longer support问题解决
背景 因为居家办公,把代码从远程clone下来之后,发现使用npm install一直失败. 提示的错误:fatal: remote error: The unauthenticated git pr ...
- Kubernetes系列(一) - kubernetes入门基本概念
目录 1. 基本概念 1.1 什么是 Kubernetes 集群 1.2 Kubernetes集群资源组成: 1.3 无状态和有状态的区别 1.3.1 无状态服务 1.3.2 有状态服务 2. Kub ...
- [LC735]行星碰撞
题目描述 给定一个整数数组 asteroids,表示在同一行的行星.对于数组中的每一个元素,其绝对值表示行星的大小,正负表示行星的移动方向(正表示向右移动,负表示向左移动).每一颗行星以相同的速度移动 ...
- 再制作个WCH-LINK下载器
用CH549可以制作成支持两种模式的WCH-LINK下载器,两种模式指的是RISC-V和DAPLINK模式. 如果用于沁恒的CH32V203等芯片,我们可以将这个下载器设置成RISC-V下载模式. 如 ...