Qt/QML 窗口阴影边框实现

Qt 同时被 2 个专栏收录
118 篇文章 25 订阅
47 篇文章 4 订阅

前言

在Qt界面开发中,很多时候为了UI的整体美观,都会在窗体添加阴影边框,这样会让整个窗体更加漂亮,用户体验会更好,那么,接下来介绍几种在项目中常用的添加阴影边框的方式,其中包括QWidget和QML两个体系的实现方法。而QGraphics体系的阴影边框实现和QWidget是一样的, 可以通用。

正文

一,QWidget实现阴影边框

QWidget实现阴影边框有几种常用的方式,如下:

1.设置带阴影边框的背景图片

这种方式最简单,直接提供一张有阴影边框的背景图片,然后在窗口中继承paintEvent函数(QGraphics体系中是paint函数),通过drawImage或者drawPixmap绘制背景。该方法的优点是实现很简单,也很容易理解。缺点是需要提供一种对应窗口大小的带阴影效果的背景图片,如果尺寸不对,那么在拉伸图片的时候可能会引起模糊的情况,效果就不是很理想。
此方法实现简单,就不单独贴代码了。

2.纯代码绘制阴影边框,没有图片

该方法是使用drawPath函数,通过循环改变阴影边框的颜色然后在窗体四周一层层的绘制阴影,这种方式在实现上较前一种方式更难理解些,代码也相对较多,但是比较通用,并且可以自己调节阴影的区域大小,比较灵活,不需要单独的阴影背景图片 。
关键代码如下:

void ShadowWidget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event)
    QPainterPath path;
    path.setFillRule(Qt::WindingFill);
    path.addRect(10,10,this->width()-20,this->height()-20);
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing,true);
    painter.fillPath(path,QBrush(Qt::white));
    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);
    }
}

这种方式是完全通过算法在窗口边框绘制阴影。

3.纯代码绘制阴影边框,有阴影图片

第三种方式通过一种固定的阴影背景图片,然后截取阴影图片,最后再绘制到窗体的四周。这种方式也很通用,在之前的项目中都用该i方式来实现,代码很容易理解,结构也很清晰。
关键代码如下:

void Widget::paintEvent(QPaintEvent *e)
{
    QPainter painter(this);
    QRect bottom(5, 136, 200, 7);
    QRect top(5, 0, 200, 3);
    QRect left(0, 3, 5, 133);
    QRect right(205, 3, 5, 133);
    QRect topRight(205, 0, 5, 3);
    QRect topLeft(0, 0, 5, 3);
    QRect bottomLeft(0, 136, 5, 7);
    QRect bottomRight(205, 136, 5, 7);
    QRect tBottom(5, this->height() - 7, this->width() - 10, 7);
    QRect tTop(5, 0, this->width() - 10, 3);
    QRect tLeft(0, 3, 5, this->height() - 10);
    QRect tRight(this->width() - 5, 3, 5, this->height() - 10);
    QRect tTopLeft(0, 0, 5, 3);
    QRect tTopRight(this->width() - 5, 0, 5, 3);
    QRect tBottomLeft(0, this->height() - 7, 5, 7);
    QRect tBottomRight(this->width() - 5, this->height() - 7, 5, 7);
    painter.drawPixmap(tBottom, m_shadow, bottom);
    painter.drawPixmap(tTop, m_shadow, top);
    painter.drawPixmap(tLeft, m_shadow, left);
    painter.drawPixmap(tRight, m_shadow, right);
    painter.drawPixmap(tTopRight, m_shadow, topRight);
    painter.drawPixmap(tTopLeft, m_shadow, topLeft);
    painter.drawPixmap(tBottomLeft, m_shadow, bottomLeft);
    painter.drawPixmap(tBottomRight, m_shadow, bottomRight);
}

该方式是在边框内用5个像素绘制阴影效果
以下是m_shadow图片,直接右键复制到工程目录下,设置m_shadow即可,以上的方式对widget大小没影响,都能用。
这里写图片描述

二,QML实现阴影效果

由于QML有着强大的绘图机制,再加上其丰富的动画效果,可以快速实现很复杂的界面,所以QML很适合移动端的开发,而在移动端窗体都是全屏,只有某些窗口部件会有阴影边框,接下来看看QML中对窗口部件的阴影效果实现。

1.给窗口添加BorderImage

这种方式类似于QWidget中通过阴影图片来设置阴影边框的方式,代码结构很简单,前提是需要准备一张阴影的图片。
示例如下:

ShadowRectangle.qml

Item{

    property alias color: rectangle.color
    property alias source: image.source


    BorderImage {
        anchors.fill: rectangle
        anchors {
            leftMargin: -6
            topMargin: -6
            rightMargin: -8
            bottomMargin: -8
        }
        border {
            left: 10
            top: 10
            right: 10
            bottom: 10
        }
        source: "shadow.png"
        smooth: true
    }
    Rectangle {
        id: rectangle
        anchors.fill: parent
        Image{
            id:image
            anchors.fill: rectangle
            fillMode: Image.PreserveAspectFit
            smooth: true
        }
    }
}

shadows_test.qml

Rectangle {
    width: 300
    height: 200

    color:"gray"

    ShadowRectangle{
        anchors.centerIn: parent
        width: 200
        height: 100
        color:"blue"
    }
    ShadowRectangle{
        anchors.centerIn: parent
        width: 150
        height: 70
        color:"red"
    }
    ShadowRectangle{
        anchors.centerIn: parent
        width: 100
        height: 40
//        color:"green"
        source: "1.jpg"
    }

}

效果图如下:
这里写图片描述

2.利用QML提供的组件来实现

QML中自带组件DropShadow可以实现阴影效果,该组件功能很强大, 提供了很多阴影效果,具体的可以查看Qt帮助文档。使用方式也很简单

示例如下:

Item {
    width: 300
    height: 300

    Rectangle {
        anchors.fill: parent
    }

    Image {
        id: butterfly
        source: "images/butterfly.png"
        sourceSize: Qt.size(parent.width, parent.height)
        smooth: true
        visible: false
    }

    DropShadow {
        anchors.fill: butterfly
        horizontalOffset: 3
        verticalOffset: 3
        radius: 8.0
        samples: 16
        color: "#80000000"
        source: butterfly
    }
}

这里写图片描述
可以将以上示例中的butterfly图片换成别的组件,一样的可以实现阴影效果,如下示例:

Rectangle {
    width: 500
    height: 500
    Rectangle{
        width: 300
        height: 300
        id:rect
        anchors.centerIn: parent
        color:"red"
    }

    DropShadow {
        anchors.fill: rect
        horizontalOffset: 3
        verticalOffset: 3
        radius: 8.0
        samples: 16
        color: "#80000000"
        source: rect
    }
}

这里写图片描述
更多的阴影效果请查看Qt帮助文档。

  • 1
    点赞
  • 0
    评论
  • 10
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 代码科技 设计师:Amelia_0503 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值