当前位置: 首页 > news >正文

基于Qt实现的窗口半透明流动背景

背景

  • 基于c++ & Qt实现的半透明渐变色窗口背景

先看效果 (gif录制掉帧,请自行编译源码查看,效果比gif流畅)

recording

完整源码

GradientWidget.h

#ifndef GRADIENTWIDGET_H
#define GRADIENTWIDGET_H#include <QWidget>
#include <QColor>
#include <QPointF>class QTimer;
class QParallelAnimationGroup;class GradientWidget : public QWidget
{Q_OBJECTQ_PROPERTY(QColor startColor READ startColor WRITE setStartColor)Q_PROPERTY(QColor endColor READ endColor WRITE setEndColor)Q_PROPERTY(QPointF startPoint READ startPoint WRITE setStartPoint)Q_PROPERTY(QPointF endPoint READ endPoint WRITE setEndPoint)public:GradientWidget(QWidget* parent = nullptr);~GradientWidget();QColor startColor() const;QColor endColor() const;QPointF startPoint() const;QPointF endPoint() const;public slots:void setStartColor(const QColor& color);void setEndColor(const QColor& color);void setStartPoint(const QPointF& point);void setEndPoint(const QPointF& point);protected:void paintEvent(QPaintEvent* event) override;void resizeEvent(QResizeEvent* event) override;// 添加鼠标事件以实现无边框窗口拖动void mousePressEvent(QMouseEvent* event) override;void mouseMoveEvent(QMouseEvent* event) override;private slots:void updateAnimation();private:QColor getRandomSoftColor();QPointF getRandomPointOnEdge();QTimer* m_timer;QParallelAnimationGroup* m_animationGroup;QColor m_startColor;QColor m_endColor;QPointF m_startPoint;QPointF m_endPoint;// 用于窗口拖动的成员变量QPoint m_dragPosition;
};#endif // GRADIENTWIDGET_H

GradientWidget.cpp

#include "gradientwidget.h"
#include <QPainter>
#include <QLinearGradient>
#include <QPaintEvent>
#include <QMouseEvent>
#include <QTimer>
#include <QRandomGenerator>
#include <QPropertyAnimation>
#include <QParallelAnimationGroup>
#include <QEasingCurve>GradientWidget::GradientWidget(QWidget* parent): QWidget(parent)
{// --- 新增:为半透明和无边框进行设置 ---setWindowFlags(Qt::FramelessWindowHint);setAttribute(Qt::WA_TranslucentBackground, true);// 初始化颜色和渐变点m_startColor = getRandomSoftColor();m_endColor = getRandomSoftColor();m_startPoint = getRandomPointOnEdge();m_endPoint = getRandomPointOnEdge();// 创建动画组m_animationGroup = new QParallelAnimationGroup(this);// 为四个属性创建动画auto setupAnimation = [this](const QByteArray& propertyName){QPropertyAnimation* anim = new QPropertyAnimation(this, propertyName, this);anim->setDuration(5000); // 延长动画时间,让变化更柔和anim->setEasingCurve(QEasingCurve::InOutSine);m_animationGroup->addAnimation(anim);return anim;};setupAnimation("startColor");setupAnimation("endColor");setupAnimation("startPoint");setupAnimation("endPoint");// 创建定时器m_timer = new QTimer(this);connect(m_timer, &QTimer::timeout, this, &GradientWidget::updateAnimation);m_timer->start(4500); // 时间比动画时长略短,实现无缝连接updateAnimation(); // 立即开始第一次动画
}GradientWidget::~GradientWidget() {}void GradientWidget::paintEvent(QPaintEvent* event)
{Q_UNUSED(event);QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);// 注意:由于设置了WA_TranslucentBackground,我们不需要手动清除背景// 直接绘制带Alpha通道的渐变即可QLinearGradient gradient(m_startPoint, m_endPoint);gradient.setColorAt(0, m_startColor);gradient.setColorAt(1, m_endColor);painter.fillRect(rect(), gradient);
}void GradientWidget::resizeEvent(QResizeEvent* event)
{updateAnimation();QWidget::resizeEvent(event);
}// --- 新增:鼠标事件处理 ---
void GradientWidget::mousePressEvent(QMouseEvent* event)
{if (event->button() == Qt::LeftButton){m_dragPosition = event->globalPos() - frameGeometry().topLeft();event->accept();}
}void GradientWidget::mouseMoveEvent(QMouseEvent* event)
{if (event->buttons() & Qt::LeftButton){move(event->globalPos() - m_dragPosition);event->accept();}
}void GradientWidget::updateAnimation()
{m_animationGroup->stop();// 更新起始颜色动画的目标值auto startColorAnim = static_cast<QPropertyAnimation*>(m_animationGroup->animationAt(0));startColorAnim->setStartValue(m_startColor);startColorAnim->setEndValue(getRandomSoftColor()); // 使用新函数// 更新结束颜色动画的目标值auto endColorAnim = static_cast<QPropertyAnimation*>(m_animationGroup->animationAt(1));endColorAnim->setStartValue(m_endColor);endColorAnim->setEndValue(getRandomSoftColor()); // 使用新函数// 更新起始点动画的目标值auto startPointAnim = static_cast<QPropertyAnimation*>(m_animationGroup->animationAt(2));startPointAnim->setStartValue(m_startPoint);startPointAnim->setEndValue(getRandomPointOnEdge());// 更新结束点动画的目标值auto endPointAnim = static_cast<QPropertyAnimation*>(m_animationGroup->animationAt(3));endPointAnim->setStartValue(m_endPoint);endPointAnim->setEndValue(getRandomPointOnEdge());m_animationGroup->start();
}/*** @brief 生成一个柔和的、半透明的随机颜色* RGB分量范围:60 ~ 230* Alpha分量固定:220 (约86%不透明度)*/
QColor GradientWidget::getRandomSoftColor()
{int r = 60 + QRandomGenerator::global()->bounded(171); // 范围 60-230int g = 60 + QRandomGenerator::global()->bounded(171); // 范围 60-230int b = 60 + QRandomGenerator::global()->bounded(171); // 范围 60-230return QColor(r, g, b, 220); // 固定Alpha值
}QPointF GradientWidget::getRandomPointOnEdge()
{if (width() == 0 || height() == 0) return QPointF(0, 0);int edge = QRandomGenerator::global()->bounded(4);switch (edge){case 0: return QPointF(QRandomGenerator::global()->bounded(width()), 0); // Topcase 1: return QPointF(width(), QRandomGenerator::global()->bounded(height())); // Rightcase 2: return QPointF(QRandomGenerator::global()->bounded(width()), height()); // Bottomcase 3:default: return QPointF(0, QRandomGenerator::global()->bounded(height())); // Left}
}// Getters and Setters
QColor GradientWidget::startColor() const { return m_startColor; }
QColor GradientWidget::endColor() const { return m_endColor; }
QPointF GradientWidget::startPoint() const { return m_startPoint; }
QPointF GradientWidget::endPoint() const { return m_endPoint; }void GradientWidget::setStartColor(const QColor& color)
{m_startColor = color;update();
}void GradientWidget::setEndColor(const QColor& color)
{m_endColor = color;update();
}void GradientWidget::setStartPoint(const QPointF& point)
{m_startPoint = point;update();
}void GradientWidget::setEndPoint(const QPointF& point)
{m_endPoint = point;update();
}

main.cpp

include "gradientwidget.h"
#include <QApplication>int main(int argc, char* argv[])
{QApplication a(argc, argv);GradientWidget w;w.setWindowTitle("Dynamic Gradient Background");w.resize(800, 600);w.show();return a.exec();
}
http://www.jsqmd.com/news/41898/

相关文章:

  • 2025河南郑州锅炉设备/改造/安装/维修最新TOP5推荐:质造升级驱动产业新发展,河南中原地区优选
  • 2025年11月冷媒剂厂家推荐榜:五家主流品牌综合对比与评价
  • 2025年11月防冻液厂家推荐榜:权威评测五强对比一览
  • 2025年11月防冻液厂家对比榜:五强性能数据与资质验证全记录
  • steam营销分析
  • 2025年11月冷媒剂厂家评测榜:从资质到应用全场景解析
  • 心情助手3.07正式版,吃喝镇
  • 在ec2上部署Qwen2.5omini和Qwen3omini模型
  • 分布式计算通信原语的抽象模型
  • 【shell】每日shell练习:安全日志入侵检测/专业的系统配置文件合规检查
  • 2025年第39周数字取证与事件响应技术动态
  • 第三次算法作业
  • 2025/11/16
  • 实用指南:《vector.pdf 深度解读:vector 核心接口、扩容机制与迭代器失效解决方案》
  • 【MX-S11】梦熊 NOIP 2025 模拟赛 3 WAOI R7 FeOI R6.5(同步赛)总结分析
  • 2025 年 11 月旅游船厂家推荐排行榜,新能源电动旅游船,画舫仿古双层豪华旅游船,定制旅游船,玻璃钢钢质铝合金旅游船公司精选
  • 2025 年 11 月观光船厂家推荐排行榜,新能源观光船,电动观光船,画舫观光船,仿古观光船,双层观光船,豪华观光船,定制观光船,玻璃钢观光船,钢质观光船,铝合金观光船公司推荐
  • [Win] [ffmpeg] Win下如何安装ffmpeg
  • 开发日记
  • [Win] [包管理器] powershell 安装 choco
  • win11 报错
  • 数据结构——二十四、图(王道408) - 实践
  • 本地CMake编译opencv库(Mingw)
  • C# Avalonia 18- ControlTemplates - ColorPickerUserControlTest
  • 《重生之我成为世界顶级黑客》第四章:实践出真知
  • Spring AI Alibaba 项目源码学习(九)-其他继承BaseAgent
  • Linux进程状态 - 教程
  • mybatis_generate_demo
  • 换歌换歌
  • GaN 器件第三象限导通特性