QtShadowDialog
QWidget实现无边框带阴影窗体技术调研报告
一、实现原理
- 核心机制
无边框实现:通过
Qt::FramelessWindowHint
标志去除系统默认边框。
- 阴影效果:
方案一:使用
QGraphicsDropShadowEffect
类实现快速阴影。
方案二:重写
paintEvent
使用
QPainter
绘制自定义阴影。
- 窗口状态管理
全屏/局部切换:通过
showFullScreen()
和
showNormal()
控制窗口状态,结合
windowState()
判断当前状态。
透明背景:
setAttribute(Qt::WA_TranslucentBackground)
确保阴影可见。
二、实现流程图
三、代码实现(方案二:QPainter绘制)
#include <QWidget>
#include <QPainter>
#include <QMouseEvent>
#include <QPropertyAnimation>
class ShadowWindow : public QWidget {
Q_OBJECT
public:
ShadowWindow(QWidget *parent = nullptr) : QWidget(parent) {
// 无边框设置
setWindowFlags(Qt::FramelessWindowHint);
setAttribute(Qt::WA_TranslucentBackground);
// 阴影参数
m_radius = 10; // 圆角半径
m_offset = QPoint(0, 0); // 阴影偏移
m_blurRadius = 20; // 阴影模糊半径
m_color = QColor(0, 0, 0, 100); // 阴影颜色
}
protected:
void paintEvent(QPaintEvent *event) override {
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
// 绘制阴影
QLinearGradient gradient(rect().topLeft(), rect().bottomRight());
gradient.setColorAt(0, m_color);
gradient.setColorAt(1, Qt::transparent);
painter.setBrush(gradient);
painter.setPen(Qt::NoPen);
painter.drawRect(rect().adjusted(-m_blurRadius, -m_blurRadius, m_blurRadius, m_blurRadius));
// 绘制圆角主体
QPainterPath path;
path.addRoundedRect(rect().adjusted(m_blurRadius, m_blurRadius, -m_blurRadius, -m_blurRadius), m_radius, m_radius);
painter.fillPath(path, Qt::white);
}
void mousePressEvent(QMouseEvent *event) {
if (event->button() == Qt::LeftButton) {
m_dragPos = event->globalPos() - frameGeometry().topLeft();
event->accept();
}
}
void mouseMoveEvent(QMouseEvent *event) {
if (event->buttons() & Qt::LeftButton) {
move(event->globalPos() - m_dragPos);
event->accept();
}
}
private:
int m_radius;
QPoint m_offset;
int m_blurRadius;
QColor m_color;
QPoint m_dragPos;
};
四、优化参数配置表
参数 | 作用描述 | 推荐取值范围 | 示例代码片段 |
---|---|---|---|
m_radius |
圆角半径 | 5-20像素 | m_radius = 10; |
m_blurRadius |
阴影模糊半径 | 10-30像素 | m_blurRadius = 20; |
m_color |
阴影颜色(带透明度) | QColor(0,0,0,100) |
m_color = QColor(0,0,0,100); |
AA_EnableHighDpi |
高DPI缩放适配 | true/false |
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); |
五、技术调研对比
方案 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
QGraphicsDropShadow | 代码简洁,跨平台兼容性好 | 高DPI下可能出现错位1 | 快速开发,简单阴影需求 |
QPainter自定义绘制 | 完全控制阴影形状和动画 | 需要手动处理性能优化 | 高级视觉效果,动画需求 |
系统API调用 | 原生系统阴影效果 | 跨平台实现复杂9 | 对系统一致性要求高的场景 |
六、结构图说明
七、全屏与局部状态处理
void ShadowWindow::toggleWindowState() {
if (isFullScreen()) {
showNormal();
// 调整阴影参数
m_blurRadius = 20;
update();
} else {
showFullScreen();
// 优化全屏阴影
m_blurRadius = 10;
update();
}
}
八、注意事项
- 性能优化:复杂阴影建议使用
QPainter.setRenderHint(QPainter::HighQualityAntialiasing)
。 - 跨平台测试:Windows/Linux/Mac的阴影渲染可能存在差异,需单独测试。
- 动画兼容性:结合
QPropertyAnimation
时需注意阴影效果的平滑过渡。
完整代码
作者 | 郑天佐 | |
邮箱 | zhengtianzuo06@163.com | |
主页 | http://www.zhengtianzuo.com | |
github | https://github.com/zhengtianzuo |