Qt:基于widget方式的窗口阴影边框的实现

方法1:九宫格背景图片法

此方法的原理是利用一张做好的阴影图作为背景图片,窗口上的所有内容包括背景不要遮挡边框,得以实现。

1. 在窗口的构造函数中增加如下代码:

setWindowFlags(Qt::FramelessWindowHint);               //设置为无边框窗口
setAttribute(Qt::WA_TranslucentBackground, true);      //设置为透明背景

2. 在窗口的样式表中增加如下代码:

border-width: 8px;
border-image: url(:/widget_border.png) 8 8 8 8;

设置窗口的边框宽度为8;以拉伸方式将阴影背景png设为背景图片,并用九宫格方式将阴影部分(8像素宽)切出来。图片如下:



3. 为窗口添加背景:

    由于采用了透明窗口,如果不对窗口的背景进行填充则鼠标的动作会被穿透。可以用颜色或位图在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());

    注:1.阴影背景的边框宽度是8,而在painter里留下的边框宽度为6。

4. 重绘widget

     在paintEvent中增加:

    

    QStyleOption opt;
    opt.init(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);

方法1的局限性:border-image如果是png格式,运行中改变窗口大小时九宫格的大小会被拉伸,造成阴影宽度随着窗口大小变化。


方法2:自绘边框

此方法的原理是利用painter在窗口的边框宽度中由里向外一圈圈地画颜色渐浅的矩形得以实现。

1. 设置窗口为无边框、透明背景。参考方法1的步骤1。

2. 在painterEvent中增加如下代码:


    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);
    }
 
  

3. 为窗口增加背景。参考方法1的步骤3。


附1:圆角窗口的实现

        在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());





你可能感兴趣的:(Qt)