此方法的原理是利用一张做好的阴影图作为背景图片,窗口上的所有内容包括背景不要遮挡边框,得以实现。
setWindowFlags(Qt::FramelessWindowHint); //设置为无边框窗口
setAttribute(Qt::WA_TranslucentBackground, true); //设置为透明背景
border-width: 8px;
border-image: url(:/widget_border.png) 8 8 8 8;
由于采用了透明窗口,如果不对窗口的背景进行填充则鼠标的动作会被穿透。可以用颜色或位图在painterEvent中填充。
颜色填充:
QPainter painter(this);
painter.fillRect(6,6,width()-12,height()-12,QColor(232, 236, 247));
位图填充:
QPainter painter(this);
QPixmap backBmp(":/Background.bmp");
painter.drawPixmap(6,6,width()-12,height()-12,backBmp,0,0,backBmp.width(),backBmp.height());
在paintEvent中增加:
QStyleOption opt;
opt.init(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);
方法1的局限性:border-image如果是png格式,运行中改变窗口大小时九宫格的大小会被拉伸,造成阴影宽度随着窗口大小变化。
此方法的原理是利用painter在窗口的边框宽度中由里向外一圈圈地画颜色渐浅的矩形得以实现。
QPainter painter(this);
QColor color(0, 0, 0, 0);
for(int i=0; i<6; i++)
{
QPainterPath path;
path.setFillRule(Qt::WindingFill);
path.addRect(6-i, 6-i, this->width()-(6-i)*2, this->height()-(6-i)*2);
color.setAlpha(50 - i*10);
painter.setPen(color);
painter.drawPath(path);
}
在painteEvent中增加:
QBitmap bmp(this->size());
bmp.fill();
QPainter p(&bmp);
p.setPen(Qt::NoPen);
p.setBrush(Qt::black);
p.drawRoundedRect(bmp.rect(),8,8);
setMask(bmp);
在步骤3中贴位图时修剪为圆角:
QPixmap backBmp(":/Background.bmp");
QBitmap maskbmp(backBmp.size());
maskbmp.fill();
QPainter maskpainter(&maskbmp);
maskpainter.setPen(Qt::NoPen);
maskpainter.setBrush(Qt::black);
maskpainter.drawRoundedRect(maskbmp.rect(),8,8);
backBmp.setMask(maskbmp);
painter.setRenderHints(QPainter::SmoothPixmapTransform); //消位图锯齿
painter.drawPixmap(6,6,width()-12,height()-12,backBmp,0,0,backBmp.width(),backBmp.height());