diff --git a/src/customwidget.cpp b/src/customwidget.cpp index 4de88d2..4e89229 100644 --- a/src/customwidget.cpp +++ b/src/customwidget.cpp @@ -12,15 +12,17 @@ CustomWidget::CustomWidget(QWidget *parent) , m_rotationAngle(0.0) , m_wavePhase(0.0) , m_startTime(QDateTime::currentDateTime()) + , m_lastLockDuration(0) + , m_lockCount(0) { // 设置窗口属性 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"; } @@ -36,17 +38,31 @@ void CustomWidget::setPaintingEnabled(bool enabled) { if (m_paintingEnabled != enabled) { m_paintingEnabled = enabled; - + if (enabled) { qDebug() << "Painting ENABLED - Resuming animations"; m_animationTimer->start(16); + + // 解锁:计算锁屏持续时间 + if (m_lastLockTime.isValid()) { + QDateTime unlockTime = QDateTime::currentDateTime(); + m_lastLockDuration = m_lastLockTime.secsTo(unlockTime); + qDebug() << "Screen was locked for" << m_lastLockDuration << "seconds"; + } + m_startTime = QDateTime::currentDateTime(); } else { qDebug() << "Painting DISABLED - Stopping animations"; m_animationTimer->stop(); + + // 锁屏:记录锁屏时间 m_pauseTime = QDateTime::currentDateTime(); + m_lastLockTime = m_pauseTime; + m_lockCount++; + qDebug() << "Screen locked at" << m_lastLockTime.toString("yyyy-MM-dd hh:mm:ss") + << "- Lock count:" << m_lockCount; } - + // 触发重绘以更新状态显示 update(); } @@ -76,12 +92,12 @@ void CustomWidget::onAnimationTimer() 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(); } @@ -90,48 +106,48 @@ void CustomWidget::onAnimationTimer() 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); @@ -143,60 +159,60 @@ void CustomWidget::drawBackground(QPainter &painter) { // 绘制渐变背景 QLinearGradient gradient(0, 0, width(), height()); - + // 根据时间变化颜色 double time = m_rotationAngle / 360.0; int r1 = static_cast(100 + 50 * sin(time * 2 * M_PI)); int g1 = static_cast(150 + 50 * sin(time * 2 * M_PI + M_PI / 3)); int b1 = static_cast(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(radius * cos(angle)); int y = static_cast(radius * sin(angle)); - + QColor color; color.setHsv((i * 360 / 8 + static_cast(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; @@ -204,17 +220,17 @@ void CustomWidget::drawWaveEffect(QPainter &painter) 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; @@ -222,36 +238,36 @@ void CustomWidget::drawWaveEffect(QPainter &painter) 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" @@ -260,22 +276,70 @@ void CustomWidget::drawStatusInfo(QPainter &painter) ).arg(m_frameCount) .arg(static_cast(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); - + + if (m_lastLockTime.isValid()) { + drawLockInfo(painter); + } + // 绘制提示信息 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(); -} \ No newline at end of file +} + +void CustomWidget::drawLockInfo(QPainter &painter) +{ + QFont infoFont = painter.font(); + QRect lockInfoRect(10, 180, 350, 110); + painter.fillRect(lockInfoRect, QColor(60, 0, 60, 180)); + + painter.setPen(QColor(255, 200, 255)); + infoFont.setBold(true); + infoFont.setPointSize(11); + painter.setFont(infoFont); + painter.drawText(lockInfoRect.adjusted(10, 5, -10, -5), Qt::AlignLeft | Qt::AlignTop, + "Last Lock Info:"); + + infoFont.setBold(false); + infoFont.setPointSize(11); + painter.setFont(infoFont); + painter.setPen(QColor(255, 220, 255)); + + // 格式化锁屏时长 + QString durationStr; + if (m_lastLockDuration < 60) { + durationStr = QString("%1 seconds").arg(m_lastLockDuration); + } else if (m_lastLockDuration < 3600) { + int minutes = m_lastLockDuration / 60; + int seconds = m_lastLockDuration % 60; + durationStr = QString("%1m %2s").arg(minutes).arg(seconds); + } else { + int hours = m_lastLockDuration / 3600; + int minutes = (m_lastLockDuration % 3600) / 60; + int seconds = m_lastLockDuration % 60; + durationStr = QString("%1h %2m %3s").arg(hours).arg(minutes).arg(seconds); + } + + QString lockInfo = QString( + "\nLock Time: %1\n" + "Duration: %2\n" + "Total Locks: %3" + ).arg(m_lastLockTime.toString("yyyy-MM-dd hh:mm:ss")) + .arg(durationStr) + .arg(m_lockCount); + + painter.drawText(lockInfoRect.adjusted(10, 25, -10, -5), Qt::AlignLeft | Qt::AlignTop, lockInfo); +} diff --git a/src/customwidget.h b/src/customwidget.h index 4f47326..9a39127 100644 --- a/src/customwidget.h +++ b/src/customwidget.h @@ -10,7 +10,7 @@ /** * @brief 自定义绘制组件类 - * + * * 这个组件会持续进行动画绘制,展示屏幕锁定检测的效果 * 当屏幕锁定时,会自动停止所有Paint事件 */ @@ -83,6 +83,12 @@ private: */ void drawStatusInfo(QPainter &painter); + /** + * @brief 绘制锁屏信息 + * @param painter 绘制器 + */ + void drawLockInfo(QPainter &painter); + private: QTimer *m_animationTimer; // 动画定时器 bool m_paintingEnabled; // 绘制是否启用 @@ -91,6 +97,9 @@ private: double m_wavePhase; // 波浪相位 QDateTime m_startTime; // 开始时间 QDateTime m_pauseTime; // 暂停时间 + QDateTime m_lastLockTime; // 上次锁屏时间 + qint64 m_lastLockDuration; // 上次锁屏持续时长(秒) + int m_lockCount; // 锁屏次数 }; -#endif // CUSTOMWIDGET_H \ No newline at end of file +#endif // CUSTOMWIDGET_H diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 271baf0..c4914aa 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -21,35 +21,35 @@ MainWindow::MainWindow(QWidget *parent) { setWindowTitle("Qt Screen Lock Detection Demo"); setMinimumSize(800, 600); - + // 初始化锁屏检测器 m_lockDetector = new ScreenLockDetector(this); - + // 初始化UI setupUI(); - + // 设置信号连接 setupConnections(); - + // 初始化锁屏检测器 bool initOk = m_lockDetector->initialize(); if (!initOk) { - QMessageBox::warning(this, - "Warning", + QMessageBox::warning(this, + "Warning", "Failed to initialize screen lock detector.\n" "The application will continue to run, but screen lock detection may not work.\n\n" "This is normal if you're not running on a supported Linux desktop environment."); } - + // 创建状态更新定时器 m_updateTimer = new QTimer(this); connect(m_updateTimer, &QTimer::timeout, this, &MainWindow::updateStatusDisplay); m_updateTimer->start(100); // 每100ms更新一次状态显示 - + // 初始化状态显示 updateStatusDisplay(); updateButtonStates(); - + qDebug() << "MainWindow initialized"; } @@ -66,55 +66,55 @@ void MainWindow::setupUI() // 创建中央窗口部件 m_centralWidget = new QWidget(this); setCentralWidget(m_centralWidget); - + m_mainLayout = new QVBoxLayout(m_centralWidget); m_mainLayout->setSpacing(10); m_mainLayout->setContentsMargins(10, 10, 10, 10); - + // 创建自定义绘制组件 m_customWidget = new CustomWidget(this); m_mainLayout->addWidget(m_customWidget, 1); - + // 创建控制面板 m_controlGroup = new QGroupBox("Manual Control", this); QHBoxLayout *controlLayout = new QHBoxLayout(m_controlGroup); - + m_enablePaintBtn = new QPushButton("Enable Painting", this); m_disablePaintBtn = new QPushButton("Disable Painting", this); m_resetFrameBtn = new QPushButton("Reset Frame Count", this); - + m_enablePaintBtn->setMinimumHeight(35); m_disablePaintBtn->setMinimumHeight(35); m_resetFrameBtn->setMinimumHeight(35); - + controlLayout->addWidget(m_enablePaintBtn); controlLayout->addWidget(m_disablePaintBtn); controlLayout->addWidget(m_resetFrameBtn); controlLayout->addStretch(); - + m_mainLayout->addWidget(m_controlGroup); - + // 创建状态显示面板 m_statusGroup = new QGroupBox("Status Information", this); QVBoxLayout *statusLayout = new QVBoxLayout(m_statusGroup); - + m_lockStatusLabel = new QLabel("Screen Lock Status: Unknown", this); m_paintStatusLabel = new QLabel("Painting Status: Unknown", this); m_frameCountLabel = new QLabel("Frame Count: 0", this); m_detectorStatusLabel = new QLabel("Detector Status: Initializing...", this); - + QFont statusFont; statusFont.setPointSize(10); m_lockStatusLabel->setFont(statusFont); m_paintStatusLabel->setFont(statusFont); m_frameCountLabel->setFont(statusFont); m_detectorStatusLabel->setFont(statusFont); - + statusLayout->addWidget(m_detectorStatusLabel); statusLayout->addWidget(m_lockStatusLabel); statusLayout->addWidget(m_paintStatusLabel); statusLayout->addWidget(m_frameCountLabel); - + m_mainLayout->addWidget(m_statusGroup); } @@ -123,20 +123,20 @@ void MainWindow::setupConnections() // 连接锁屏检测器信号 connect(m_lockDetector, &ScreenLockDetector::screenLocked, this, &MainWindow::onScreenLocked); - + connect(m_lockDetector, &ScreenLockDetector::screenUnlocked, this, &MainWindow::onScreenUnlocked); - + connect(m_lockDetector, &ScreenLockDetector::lockStateChanged, this, &MainWindow::onLockStateChanged); - + // 连接按钮信号 connect(m_enablePaintBtn, &QPushButton::clicked, this, &MainWindow::onEnablePaintingClicked); - + connect(m_disablePaintBtn, &QPushButton::clicked, this, &MainWindow::onDisablePaintingClicked); - + connect(m_resetFrameBtn, &QPushButton::clicked, this, &MainWindow::onResetFrameCountClicked); } @@ -144,13 +144,12 @@ void MainWindow::setupConnections() void MainWindow::onScreenLocked() { qDebug() << "MainWindow: Screen locked event received"; - + // 停止绘制 if (m_customWidget) { m_customWidget->setPaintingEnabled(false); - m_customWidget->resetFrameCount(); } - + updateStatusDisplay(); updateButtonStates(); } @@ -158,12 +157,12 @@ void MainWindow::onScreenLocked() void MainWindow::onScreenUnlocked() { qDebug() << "MainWindow: Screen unlocked event received"; - + // 恢复绘制 if (m_customWidget) { m_customWidget->setPaintingEnabled(true); } - + updateStatusDisplay(); updateButtonStates(); } @@ -171,12 +170,12 @@ void MainWindow::onScreenUnlocked() void MainWindow::onLockStateChanged(bool locked) { qDebug() << "MainWindow: Lock state changed to:" << (locked ? "LOCKED" : "UNLOCKED"); - + // 根据锁屏状态自动启用/禁用绘制 if (m_customWidget) { m_customWidget->setPaintingEnabled(!locked); } - + updateStatusDisplay(); updateButtonStates(); } @@ -186,7 +185,7 @@ void MainWindow::updateStatusDisplay() if (!m_lockDetector) { return; } - + // 更新检测器状态 QString detectorStatus = "Detector Status: "; if (m_lockDetector) { @@ -195,7 +194,7 @@ void MainWindow::updateStatusDisplay() detectorStatus += "Not Available"; } m_detectorStatusLabel->setText(detectorStatus); - + // 更新锁屏状态 bool isLocked = m_lockDetector->isScreenLocked(); QString lockStatus = "Screen Lock Status: "; @@ -205,7 +204,7 @@ void MainWindow::updateStatusDisplay() lockStatus += "🔓 UNLOCKED"; } m_lockStatusLabel->setText(lockStatus); - + // 更新绘制状态 bool isPainting = m_customWidget ? m_customWidget->isPaintingEnabled() : false; QString paintStatus = "Painting Status: "; @@ -215,7 +214,7 @@ void MainWindow::updateStatusDisplay() paintStatus += "✗ DISABLED (Stopped)"; } m_paintStatusLabel->setText(paintStatus); - + // 更新帧计数 int frameCount = m_customWidget ? m_customWidget->getPaintFrameCount() : 0; QString frameCountStr = QString("Frame Count: %1 frames").arg(frameCount); @@ -233,11 +232,11 @@ void MainWindow::updateButtonStates() void MainWindow::onEnablePaintingClicked() { qDebug() << "Manual enable painting clicked"; - + if (m_customWidget) { m_customWidget->setPaintingEnabled(true); } - + updateStatusDisplay(); updateButtonStates(); } @@ -245,11 +244,11 @@ void MainWindow::onEnablePaintingClicked() void MainWindow::onDisablePaintingClicked() { qDebug() << "Manual disable painting clicked"; - + if (m_customWidget) { m_customWidget->setPaintingEnabled(false); } - + updateStatusDisplay(); updateButtonStates(); } @@ -257,10 +256,10 @@ void MainWindow::onDisablePaintingClicked() void MainWindow::onResetFrameCountClicked() { qDebug() << "Reset frame count clicked"; - + if (m_customWidget) { m_customWidget->resetFrameCount(); } - + updateStatusDisplay(); -} \ No newline at end of file +} diff --git a/src/screenlockdetector.cpp b/src/screenlockdetector.cpp index 7611d34..390b7ea 100644 --- a/src/screenlockdetector.cpp +++ b/src/screenlockdetector.cpp @@ -78,12 +78,12 @@ void ScreenLockDetector::setLockState(bool locked) qDebug() << "## Screen lock state changed:" << (locked ? "LOCKED" : "UNLOCKED"); qDebug() << "##################################################"; - // emit lockStateChanged(locked); + emit lockStateChanged(locked); if (locked) { emit screenLocked(); } else { - // emit screenUnlocked(); + emit screenUnlocked(); } } }