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的更多相关文章

  1. Qt 创建圆角、无边框、有阴影、可拖动的窗口 good

    程序窗口的边框,标题栏等是系统管理的,Qt 不能对其进行定制,为了实现定制的边框.标题栏.关闭按钮等,需要把系统默认的边框.标题栏去掉,然后使用 Widget 来模拟它们.这里介绍使用 QSS + Q ...

  2. Qt的三套无边框窗体的方案:可按比例拖拽窗体大小的无边框窗口和几个常见的无边框实例

    一.可按比例拖拽窗体大小的无边框窗口 前几天接到一个需求,就是视频广播的窗体画面要可以拖拽,修改成了可以拖拽全屏的窗口之后,又有一个问题:视频画面也被拉伸了. 由于视频画面是有比例的,所以我们最好也能 ...

  3. qt动态库实现无边框窗体的消息处理 nativeEvent的使用

    需求: 在动态库中创建一个窗口句柄,可以给外部调用,库的调用者,通过这个句柄发送消息到底层库,库里面可以实现对消息的处理 m_FHandle=AllocateHWnd(WndProcDllMsg); ...

  4. Qt QQuickView设置成无边框无标题栏

    #include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQuickView> ...

  5. Devexpres下窗体带阴影的边框效果

    public partial class Form1 : DevExpress.XtraEditors.XtraForm { public Form1() { InitializeComponent( ...

  6. Qt 无边框窗体改变大小 完美实现(全部自己实现)

    近期,做项目用到无边框窗体,令人蛋疼的是无边框窗体大小的改变要像右边框那样,上下左右四周,而且要流畅. 网上也找了些代码,发现居然还要连接到windows事件,这显然不合常理,后来自己新建了demo, ...

  7. Qt 无边框窗体改变大小 完美实现

    近期,做项目用到无边框窗体,令人蛋疼的是无边框窗体大小的改变要像右边框那样,上下左右四周,而且要流畅. 网上也找了些代码,发现居然还要连接到windows事件,这显然不合常理,后来自己新建了demo, ...

  8. 让Qt的无边框窗口支持拖拽、Aero Snap、窗口阴影等特性

    环境:Desktop Qt 5.4.1 MSVC2013 32bit 需要的库:dwmapi.lib .user32.lib 需要头文件:<dwmapi.h> .<windowsx. ...

  9. QT模态对话框用法(在UI文件中设置Widget背景图,这个图是一个带阴影边框的图片——酷)

    QT弹出模态对话框做法: 1.新建UI文件时,一定要选择基类是QDialog的,我的选择是:Dialog without Buttons(),如下图: 2.然后在使用的时候: MyDialog dlg ...

  10. Qt自带的阴影类、跨线程问题汇总、hover相关、全屏轮子,一些思考。

    一点思考:故事的结局重不重要? 我语文不好,但是我数学不好. 我数学不好,但是我英语不好. 我英语不好,但是我物理不好. 我物理不好,但是我化学不好. 我化学不好,但是我历史不好. 我历史不好,但是我 ...

随机推荐

  1. OkHttp实现延时重试

    本文主要应用了OkHttp的Interceptor来实现自定义重试次数 虽然OkHttp自带retryOnConnectionFailure(true)方法可以实现重试,但是不支持自定义重试次数,所以 ...

  2. Qt编写视频监控系统(移动侦测/遮挡报警/区域入侵/越界侦测/报警输入输出等)

    一.前言 得益于标准的onvif协议,各大监控厂商的设备都会支持onvif协议,在onvif协议中就包括了事件订阅机制,通过这个机制,可以拿到各种报警事件,比如移动侦测/遮挡报警/区域入侵/越界侦测/ ...

  3. 正在测试和完善的CH552(CH549)USB下载之单按键带入电路实验

    一.设计理由 CH552或CH549进入USB下载,通常需要两个按键,一个控制电源的通断,一个通过串联电阻(一头接VCC或V33)冷启动时抬高UDP电平.时序上是这样的:断电--按下接UDP的轻触开关 ...

  4. Solution -「NOI Simu.」记忆

    \(\mathscr{Description}\)   长度为 \(n\) 的序列 \(A\) 初始全 \(0\), \(C=0\). 第 \(i\ge0\) 个时刻对 \(A\) 进行如下变换: \ ...

  5. manim边做边学--动画联动

    今天介绍Manim中的动画联动的技巧,在数学动画中,动画联动是常用的功能, 比如讲解平面几何中三角形与圆的位置关系变化,通过动画联动可以让圆沿着三角形的边滚动,或者让三角形的顶点在圆上移动,从而直观地 ...

  6. 第八章 AtomicInteger源码解析

    1.原子类 可以实现一些原子操作 基于CAS 下面就以AtomicInteger为例. 2.AtomicInteger 在没有AtomicInteger之前,对于一个Integer的线程安全操作,是需 ...

  7. Storm基本概念

    storm简介   场景 伴随着信息科技日新月异的发展,信息呈现出爆发式的膨胀,人们获取信息的途径也更加多样.更加便捷,同时对于信息的时效性要求也越来越高.举个搜索场景中的例子,当一个卖家发布了一条宝 ...

  8. weixueyuan-Nginx代理服务器5

    https://www.weixueyuan.net/nginx/proxy_server/ Nginx HTTP代理服务器 代理功能根据应用方式的不同可以分为正向代理和反向代理.正向代理是客户端设置 ...

  9. 第三届全国高校计算机能力挑战赛-C

    单项选择题 1.题 (3.0分) 以下叙述正确的是().  A.在C程序,至少要包含一个库函数  B.C程序的一行可以写多条语句  C.对一个C程序进行编译就可以生成可执行文件  D.C程序中的注释只 ...

  10. LeetCode 力扣 205. 同构字符串

    给定两个字符串 s 和 t ,判断它们是否是同构的. 如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的. 每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序.不同字 ...