Qt 给窗口绘制阴影
前言
最近自定义一个消息弹框,但是没加阴影之前,觉得有点扁平。然后仔细看了Qt自带的消息弹框,发现是没有加上阴影的问题。所以就在网上搜索怎么加阴影,有多种方法。写这个博客的目的是记录一下这几种方法,并且加上我对于这些方法的理解。
具体的方法有
-
重载paintEvent ,调用drawRect 或者drawRoundedRect 或者drawPath 来手绘阴影 -
使用QGraphicsDropShadowEffect 类,来绘制阴影 -
使用九图拼凑法 -
九宫格缩放阴影法
但是不管是哪种方法,都需要设置窗口的背景透明
this->setWindowFlags(Qt::FramelessWindowHint);
this->setAttribute(Qt::WA_TranslucentBackground);
重载paintEvent 法
这个方法就是重载paintEvent ,然后自己设置绘图的区域,根据阴影的大小、根据阴影的颜色,一圈一圈的去画阴影。
然后又分有三个函数来进行阴影的绘制
drawPath 这个函数的作用是绘制一个路线,路线可以由很多不同的曲线或者直线组成,这个可以绘制多边形。  绘制代码如下:
void Waiting::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
QColor color(0, 0, 0, 50);
for(int i=0; i<10; i++)
{
QPainterPath path;
path.setFillRule(Qt::WindingFill);
path.addRect(10-i, 10-i, this->width()-(10-i)*2, this->height()-(10-i)*2);
color.setAlpha(150 - qSqrt(i)*50);
painter.setPen(color);
painter.drawPath(path);
}
}
绘制效果如下: 
Tips:
drawRect 和drawRoundedRect 这两个函数分别是画矩形阴影和画带圆角的阴影,除了最后绘制的时候锁调用的函数不一样,其余都是一样的。drawRect 是绘制矩形的,drawRoundedRect 是绘制带圆角的。 
 代码如下:
void Waiting::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
QColor color(0, 0, 0, 50);
for(int i=0; i<10; i++)
{
color.setAlpha(150 - qSqrt(i)*50);
painter.setPen(color);
painter.drawRoundedRect(10-i, 10-i, this->width()-(10-i)*2, this->height()-(10-i)*2, 20, 20);
}
}
效果图如下:  
QGraphicsDropShadowEffect方法
这个类就直接用就好了,代码如下:
m_pEffect = new QGraphicsDropShadowEffect(m_background);
m_pEffect->setOffset(0, 0);
m_pEffect->setColor(QColor(QStringLiteral("black")));
m_pEffect->setBlurRadius(30);
m_background->setGraphicsEffect(m_pEffect);
Tips:
-
setOffser 这个是设置阴影的起始点位于窗口的哪个位置 -
setBlurRadius 这个是设置阴影的模糊程度,越大就越模糊
具体对比请看下图: 
使用九图拼凑法
这个方法参考一去二三里大佬的博客:Qt之阴影边框_一去二三里_新浪博客
九宫格缩放阴影法
这里是另外以为大佬的博客:Qt之使用QPainter自绘实现窗口阴影边框_前行之路还需前行-CSDN博客
我这里只对大佬的代码进行一个自我的理解,具体内容,请移步去大佬的博客。 Tips:
-
ninePatchScalePixmap 函数 iHorzSplit 和iVertSplit 这两个变量分别代表对原始的图片进行九宫格分之后的高和宽。 DstWidth 和DstHeight 这个两个变量则代表最后需要的图片的高和宽
如下图: 
|