您的位置:首页 > 编程语言 > Qt开发

Qt/QML 窗口阴影边框实现

2017-03-23 07:47 1966 查看

前言

在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帮助文档。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  qt QML 阴影