Qt 窗口阴影边框

环境:Qt 5.15 + VS2019

方法一:QGraphicsDropShadowEffect

实现方法参考链接:https://blog.csdn.net/goforwardtostep/article/details/99549750

使用此方法添加窗口阴影,会出现警告信息:

且窗口最大化与还原切换时会出现子控件刷新问题:

方法二:九宫格贴图

实现方法参考链接:https://blog.csdn.net/goforwardtostep/article/details/99549750

需要美工

方法三:paintEvent

实现方法参考链接:https://blog.csdn.net/goforwardtostep/article/details/99549750

此方法绘制圆角边框不够完美

下图右边为paintEvent使用addRoundedRect实现,左边为结合九宫格思想通过paintEvent实现

下面为上图右侧实现代码:

app_window.h

cpp 复制代码
#ifndef APP_WINDOW_H
#define APP_WINDOW_H

#include <QWidget>

namespace Ui {
class AppWindow;
}

class AppWindow : public QWidget
{
    Q_OBJECT

public:
    explicit AppWindow(QWidget *parent = nullptr);
    ~AppWindow();

protected:
    void paintEvent(QPaintEvent* event) override;

private:
    Ui::AppWindow *ui;

    //阴影宽度
    int shadowWidth_ = 15;

    //窗口圆角
    int windowRadius_ = 9;
};

#endif // APP_WINDOW_H

app_window.cpp

cpp 复制代码
#include "app_window.h"
#include "ui_app_window.h"
#include <QPainter>
#include <QPainterPath>

AppWindow::AppWindow(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::AppWindow)
{
    ui->setupUi(this);
    setAttribute(Qt::WA_TranslucentBackground); // 背景透明
    setWindowFlags(Qt::Window | Qt::FramelessWindowHint);

    QString qss = QString("background-color: rgb(255, 255, 255); border-radius:%1px").arg(windowRadius_);
    ui->widgetMain->setStyleSheet(qss);
    ui->gridLayout->setMargin(shadowWidth_);
}

AppWindow::~AppWindow()
{
    delete ui;
}

void AppWindow::paintEvent(QPaintEvent *event)
{
    int radius = shadowWidth_ + windowRadius_;
    int width = this->width();
    int height = this->height();
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true); //抗锯齿
    painter.setPen(Qt::NoPen);

    //线性渐变
    QLinearGradient linearGradient;
    linearGradient.setColorAt(0,QColor(255,0,0, 250));
    linearGradient.setColorAt(1,QColor(255,0,0, 50));

    //圆形渐变
    QRadialGradient radialGradient;
    radialGradient.setColorAt(0,QColor(255,0,0, 250));
    radialGradient.setColorAt(1,QColor(255,0,0, 50));

    //左上角
    radialGradient.setCenter(radius, radius); //中心点
    radialGradient.setRadius(radius); //半径
    radialGradient.setFocalPoint(radius, radius); //焦点
    painter.setBrush(radialGradient);
    QRectF rectf(0, 0, radius*2, radius*2);
    QPainterPath path;
    path.moveTo(radius, radius);//移动圆心
    path.arcTo(rectf, 90, 90);
    painter.drawPath(path);   //画路径(扇形)

    //左边
    linearGradient.setStart(radius, height/2);
    linearGradient.setFinalStop(0, height/2);
    painter.setBrush(linearGradient);
    path.clear();
    path.addRect(0, radius, radius, height - radius*2);
    painter.drawPath(path);

    //左下角
    radialGradient.setCenter(radius, height - radius); //中心点
    radialGradient.setRadius(radius); //半径
    radialGradient.setFocalPoint(radius, height - radius); //焦点
    painter.setBrush(radialGradient);
    path.clear();
    path.moveTo(radius, height - radius);//移动圆心
    rectf.setRect(0, height - radius*2, radius*2, radius*2);
    path.arcTo(rectf, 180, 90);
    painter.drawPath(path);   //画路径(扇形)

    //下边
    linearGradient.setStart(width/2, height - radius);
    linearGradient.setFinalStop(width/2, height);
    painter.setBrush(linearGradient);
    path.clear();
    path.addRect(radius, height - radius, width - radius*2, radius);
    painter.drawPath(path);

    //右下角
    radialGradient.setCenter(width - radius, height - radius); //中心点
    radialGradient.setRadius(radius); //半径
    radialGradient.setFocalPoint(width - radius, height - radius); //焦点
    painter.setBrush(radialGradient);
    path.clear();
    path.moveTo(width - radius, height - radius);//移动圆心
    rectf.setRect(width - radius*2, height - radius*2, radius*2, radius*2);
    path.arcTo(rectf, 270, 90);
    painter.drawPath(path);   //画路径(扇形)

    //右边
    linearGradient.setStart(width - radius, height/2);
    linearGradient.setFinalStop(width, height/2);
    painter.setBrush(linearGradient);
    path.clear();
    path.addRect(width - radius, radius, radius, height - radius*2);
    painter.drawPath(path);

    //右上角
    radialGradient.setCenter(width - radius, radius); //中心点
    radialGradient.setRadius(radius); //半径
    radialGradient.setFocalPoint(width - radius, radius); //焦点
    painter.setBrush(radialGradient);
    path.clear();
    path.moveTo(width - radius, radius);//移动圆心
    rectf.setRect(width - radius*2, 0, radius*2, radius*2);
    path.arcTo(rectf, 0, 90);
    painter.drawPath(path);   //画路径(扇形)

    //上边
    linearGradient.setStart(height/2, radius);
    linearGradient.setFinalStop(height/2, 0);
    painter.setBrush(linearGradient);
    path.clear();
    path.addRect(radius, 0, width - radius*2, radius);
    painter.drawPath(path);
}
相关推荐
锦亦之22339 小时前
QT+OSG+OSG-earth如何在窗口显示一个地球
开发语言·qt
柳鲲鹏12 小时前
编译成功!QT/6.7.2/Creator编译Windows64 MySQL驱动(MinGW版)
开发语言·qt·mysql
三玖诶12 小时前
如何在 Qt 的 QListWidget 中逐行添加和显示数据
开发语言·qt
阳光开朗_大男孩儿18 小时前
DBUS属性原理
linux·服务器·前端·数据库·qt
Alphapeople19 小时前
Qt Modbus
开发语言·qt
竹林海中敲代码19 小时前
Qt Creator 集成开发环境 常见问题
qt·qt工具常见问题
竹林海中敲代码1 天前
Qt安卓开发连接手机调试(红米K60为例)
android·qt·智能手机
长沙红胖子Qt1 天前
关于 Qt运行加载内存较大崩溃添加扩大运行内存 的解决方法
开发语言·qt·qt扩大运行内存
gopher95111 天前
qt相关面试题
开发语言·qt·面试
三玖诶1 天前
在 Qt 中使用 QLabel 设置 GIF 动态背景
开发语言·qt·命令模式