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相关、全屏轮子,一些思考。
一点思考:故事的结局重不重要? 我语文不好,但是我数学不好. 我数学不好,但是我英语不好. 我英语不好,但是我物理不好. 我物理不好,但是我化学不好. 我化学不好,但是我历史不好. 我历史不好,但是我 ...
随机推荐
- docker-compose.yml 使用说明
docker-compose.yml 结构 docker-compose.yml文件分为三个主要部分:services.networks.volumes..services主要用来定义各个容器.net ...
- Qt/C++编写超精美自定义控件(历时9年更新迭代/超202个控件/祖传原创)
一.前言 无论是哪一门开发框架,如果涉及到UI这块,肯定需要用到自定义控件,越复杂功能越多的项目,自定义控件的数量就越多,最开始的时候可能每个自定义控件都针对特定的应用场景,甚至里面带了特定的场景的一 ...
- 古早的遗传算法碰到LLM->😊AutoDAN Generating Stealthy Jailbreak Prompts on💗Aligned Large Language Models
师兄推给我的一篇ICLR,抽出时间阅读整理了附录前的内容 这次没有完全翻译,因为我想组会上分享,转成自己的话 禁止盗用,侵权必究!!!欢迎大家积极举报
- Coravel:一个可轻松实现任务调度、队列、邮件发送的开源项目
推荐一个轻量级的任务调度开源项目. 01 项目简介 Coravel是一个.NET开源任务调度库,只需简单代码.几乎零配置就可以实现多种功能柜,如任务调度.队列.缓存.事件广播和邮件发送等.该项目特点就 ...
- Python 问题汇总
一. Python 环境问题 使用pytest 在terminal中执行脚本调用python3.9, 而使用pycharm 的virtualenv 执行脚本调用的是python3.10, 由于环境不一 ...
- cpa-会计
会计整体介绍 1.总结 2.会计政策.会计估计及其变更和差错更正 3.存货 4.固定资产 5.无形资产 6.投资性房地产 7.长期股权投资与合营安排 8.资产减值 9.负债 10.职工薪酬 11.借款 ...
- weblogic-copy
一.简介 WebLogic是美国Oracle公司出品的一个application server,确切的说是一个基于JAVAEE架构的中间件,WebLogic是用于开发.集成.部署和管理大型分布式Web ...
- OxyPlot:一个功能强大、漂亮.Net跨平台开源绘图库
推荐一个支持多平台.多框架的.Net绘图库. 01 项目简介 OxyPlot是一个基于.NET开发的.跨平台的绘图库,可用于多种平台和框架,如WPF.Windows 8.Windows Phone.W ...
- https证书一键自动续期,帮你解放90天限制
前言 前几天网站证书到期,发觉证书颁发每次只能90天有效期,这谁能忍受,于是乎发觉网上有免费的一键续期脚本,真正解放我们的双手.项目如下acme.sh. 期间由于"墙"的原因,踩了 ...
- 测试 【子牙-writing】 大模型
参考:姜子牙大模型系列 | 写作模型ziya-writing开源!开箱即用,快来认领专属你的写作小助手吧 封神榜:https://github.com/IDEA-CCNL/Fengshenbang-L ...