ScreenLockDetector/src/customwidget.cpp

281 lines
7.5 KiB
C++
Raw Normal View History

2025-11-07 10:56:45 +08:00
#include "customwidget.h"
#include <QPaintEvent>
#include <QPainterPath>
#include <QDebug>
#include <cmath>
CustomWidget::CustomWidget(QWidget *parent)
: QWidget(parent)
, m_animationTimer(nullptr)
, m_paintingEnabled(true)
, m_frameCount(0)
, m_rotationAngle(0.0)
, m_wavePhase(0.0)
, m_startTime(QDateTime::currentDateTime())
{
// 设置窗口属性
setMinimumSize(600, 400);
// 创建动画定时器 - 60 FPS
m_animationTimer = new QTimer(this);
connect(m_animationTimer, &QTimer::timeout, this, &CustomWidget::onAnimationTimer);
m_animationTimer->start(16); // 约60 FPS (1000/60 ≈ 16ms)
qDebug() << "CustomWidget created, animation timer started";
}
CustomWidget::~CustomWidget()
{
if (m_animationTimer) {
m_animationTimer->stop();
}
qDebug() << "CustomWidget destroyed, total frames painted:" << m_frameCount;
}
void CustomWidget::setPaintingEnabled(bool enabled)
{
if (m_paintingEnabled != enabled) {
m_paintingEnabled = enabled;
if (enabled) {
qDebug() << "Painting ENABLED - Resuming animations";
m_animationTimer->start(16);
m_startTime = QDateTime::currentDateTime();
} else {
qDebug() << "Painting DISABLED - Stopping animations";
m_animationTimer->stop();
m_pauseTime = QDateTime::currentDateTime();
}
// 触发重绘以更新状态显示
update();
}
}
bool CustomWidget::isPaintingEnabled() const
{
return m_paintingEnabled;
}
int CustomWidget::getPaintFrameCount() const
{
return m_frameCount;
}
void CustomWidget::resetFrameCount()
{
m_frameCount = 0;
qDebug() << "Frame count reset";
}
void CustomWidget::onAnimationTimer()
{
if (m_paintingEnabled) {
// 更新动画参数
m_rotationAngle += 2.0;
if (m_rotationAngle >= 360.0) {
m_rotationAngle -= 360.0;
}
m_wavePhase += 0.05;
if (m_wavePhase >= 2 * M_PI) {
m_wavePhase -= 2 * M_PI;
}
// 触发重绘
update();
}
}
void CustomWidget::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
// 如果绘制被禁用,仅绘制一次状态信息然后返回
if (!m_paintingEnabled) {
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
// 绘制暗背景
painter.fillRect(rect(), QColor(40, 40, 40));
// 绘制禁用状态信息
painter.setPen(QColor(200, 200, 200));
QFont font = painter.font();
font.setPointSize(16);
font.setBold(true);
painter.setFont(font);
QString text = "PAINTING DISABLED\n(Screen Locked)";
painter.drawText(rect(), Qt::AlignCenter, text);
// 绘制统计信息
font.setPointSize(12);
font.setBold(false);
painter.setFont(font);
painter.setPen(QColor(150, 150, 150));
QString stats = QString("Total Frames Painted: %1\nPaused at: %2")
.arg(m_frameCount)
.arg(m_pauseTime.toString("hh:mm:ss"));
QRect statsRect = rect().adjusted(20, 0, -20, -20);
painter.drawText(statsRect, Qt::AlignBottom | Qt::AlignLeft, stats);
return;
}
// 正常绘制流程
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
// 增加帧计数
m_frameCount++;
// 绘制各个图层
drawBackground(painter);
drawRotatingCircles(painter);
drawWaveEffect(painter);
drawStatusInfo(painter);
}
void CustomWidget::drawBackground(QPainter &painter)
{
// 绘制渐变背景
QLinearGradient gradient(0, 0, width(), height());
// 根据时间变化颜色
double time = m_rotationAngle / 360.0;
int r1 = static_cast<int>(100 + 50 * sin(time * 2 * M_PI));
int g1 = static_cast<int>(150 + 50 * sin(time * 2 * M_PI + M_PI / 3));
int b1 = static_cast<int>(200 + 55 * sin(time * 2 * M_PI + 2 * M_PI / 3));
gradient.setColorAt(0, QColor(r1, g1, b1));
gradient.setColorAt(1, QColor(30, 30, 60));
painter.fillRect(rect(), gradient);
}
void CustomWidget::drawRotatingCircles(QPainter &painter)
{
painter.save();
int centerX = width() / 2;
int centerY = height() / 2;
painter.translate(centerX, centerY);
painter.rotate(m_rotationAngle);
// 绘制多个旋转的圆圈
for (int i = 0; i < 8; i++) {
double angle = (i * 2 * M_PI) / 8;
int radius = 80;
int x = static_cast<int>(radius * cos(angle));
int y = static_cast<int>(radius * sin(angle));
QColor color;
color.setHsv((i * 360 / 8 + static_cast<int>(m_rotationAngle)) % 360, 200, 255, 180);
painter.setPen(QPen(color, 2));
painter.setBrush(color);
painter.drawEllipse(QPoint(x, y), 15, 15);
}
painter.restore();
}
void CustomWidget::drawWaveEffect(QPainter &painter)
{
painter.save();
painter.setPen(QPen(QColor(255, 255, 255, 150), 2));
// 绘制正弦波
QPainterPath path;
bool firstPoint = true;
for (int x = 0; x < width(); x += 5) {
double y = height() * 0.7 + 30 * sin(m_wavePhase + x * 0.02);
if (firstPoint) {
path.moveTo(x, y);
firstPoint = false;
} else {
path.lineTo(x, y);
}
}
painter.drawPath(path);
// 绘制第二条波浪(相位偏移)
painter.setPen(QPen(QColor(255, 255, 100, 120), 2));
path = QPainterPath();
firstPoint = true;
for (int x = 0; x < width(); x += 5) {
double y = height() * 0.7 + 30 * sin(m_wavePhase + M_PI + x * 0.02);
if (firstPoint) {
path.moveTo(x, y);
firstPoint = false;
} else {
path.lineTo(x, y);
}
}
painter.drawPath(path);
painter.restore();
}
void CustomWidget::drawStatusInfo(QPainter &painter)
{
painter.save();
// 绘制标题
QFont titleFont = painter.font();
titleFont.setPointSize(18);
titleFont.setBold(true);
painter.setFont(titleFont);
painter.setPen(QColor(255, 255, 255));
QString title = "Qt Screen Lock Demo - Painting Active";
QRect titleRect(0, 20, width(), 40);
painter.drawText(titleRect, Qt::AlignCenter, title);
// 绘制统计信息
QFont infoFont = painter.font();
infoFont.setPointSize(12);
infoFont.setBold(false);
painter.setFont(infoFont);
QDateTime now = QDateTime::currentDateTime();
qint64 elapsed = m_startTime.secsTo(now);
QString stats = QString(
"Frame Count: %1\n"
"FPS: ~60\n"
"Rotation: %2°\n"
"Running Time: %3s"
).arg(m_frameCount)
.arg(static_cast<int>(m_rotationAngle))
.arg(elapsed);
// 绘制半透明背景框
QRect statsRect(10, 70, 200, 100);
painter.fillRect(statsRect, QColor(0, 0, 0, 150));
painter.setPen(QColor(200, 255, 200));
painter.drawText(statsRect.adjusted(10, 5, -10, -5), Qt::AlignLeft | Qt::AlignTop, stats);
// 绘制提示信息
painter.setPen(QColor(255, 255, 150));
infoFont.setPointSize(11);
painter.setFont(infoFont);
QString hint = "Lock your screen to see the painting stop automatically!";
QRect hintRect(0, height() - 40, width(), 30);
painter.drawText(hintRect, Qt::AlignCenter, hint);
painter.restore();
}