92 lines
3.9 KiB
C++
92 lines
3.9 KiB
C++
#include "mainwindow.h"
|
|
#include "ui_mainwindow.h"
|
|
#include <QApplication>
|
|
#include <QShortcut>
|
|
|
|
MainWindow::MainWindow(QWidget *parent)
|
|
: QMainWindow(parent), ui(new Ui::MainWindow)
|
|
{
|
|
ui->setupUi(this);
|
|
m_clock.start();
|
|
m_refreshTimer.setInterval(100);
|
|
connect(&m_refreshTimer, &QTimer::timeout, this, &MainWindow::refreshDisplay);
|
|
for (QSpinBox *spin : {ui->hoursSpin, ui->minutesSpin, ui->secondsSpin})
|
|
connect(spin, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
|
|
this, &MainWindow::durationChanged);
|
|
connect(ui->startButton, &QPushButton::clicked, this, [this] {
|
|
m_countdown.start(m_clock.elapsed());
|
|
refreshDisplay();
|
|
});
|
|
connect(ui->pauseButton, &QPushButton::clicked, this, [this] {
|
|
const auto previousState = m_countdown.state();
|
|
m_countdown.pause(m_clock.elapsed());
|
|
if (previousState == Countdown::State::Running
|
|
&& m_countdown.state() == Countdown::State::Finished
|
|
&& ui->soundCheck->isChecked())
|
|
QApplication::beep();
|
|
refreshDisplay();
|
|
});
|
|
connect(ui->resetButton, &QPushButton::clicked, this, [this] {
|
|
m_countdown.reset();
|
|
refreshDisplay();
|
|
});
|
|
connect(ui->fullscreenButton, &QPushButton::clicked, this, [this] {
|
|
if (isFullScreen()) showNormal(); else showFullScreen();
|
|
ui->fullscreenButton->setText(isFullScreen() ? tr("退出全屏") : tr("全屏显示"));
|
|
});
|
|
auto *escape = new QShortcut(QKeySequence(Qt::Key_Escape), this);
|
|
connect(escape, &QShortcut::activated, this, [this] {
|
|
if (isFullScreen()) {
|
|
showNormal();
|
|
ui->fullscreenButton->setText(tr("全屏显示"));
|
|
}
|
|
});
|
|
durationChanged();
|
|
}
|
|
|
|
MainWindow::~MainWindow() { delete ui; }
|
|
|
|
void MainWindow::durationChanged()
|
|
{
|
|
const qint64 seconds = ui->hoursSpin->value() * 3600
|
|
+ ui->minutesSpin->value() * 60 + ui->secondsSpin->value();
|
|
m_countdown.setDuration(seconds * 1000);
|
|
refreshDisplay();
|
|
}
|
|
|
|
void MainWindow::refreshDisplay()
|
|
{
|
|
const qint64 now = m_clock.elapsed();
|
|
const auto previousState = m_countdown.state();
|
|
m_countdown.update(now);
|
|
const auto state = m_countdown.state();
|
|
const bool running = state == Countdown::State::Running;
|
|
const bool paused = state == Countdown::State::Paused;
|
|
if (running && !m_refreshTimer.isActive()) m_refreshTimer.start();
|
|
if (!running) m_refreshTimer.stop();
|
|
const qint64 remaining = m_countdown.remaining(now);
|
|
// 向上取整:还剩 1 毫秒时显示 1 秒,真正到时才显示零。
|
|
const qint64 seconds = (remaining + 999) / 1000;
|
|
ui->timeLabel->setText(QStringLiteral("%1:%2:%3")
|
|
.arg(seconds / 3600, 2, 10, QLatin1Char('0'))
|
|
.arg((seconds / 60) % 60, 2, 10, QLatin1Char('0'))
|
|
.arg(seconds % 60, 2, 10, QLatin1Char('0')));
|
|
ui->progressBar->setValue(m_countdown.duration() == 0 ? 0
|
|
: static_cast<int>(remaining * 1000 / m_countdown.duration()));
|
|
ui->durationGroup->setEnabled(!running && !paused);
|
|
ui->startButton->setEnabled(!running && m_countdown.duration() > 0);
|
|
ui->pauseButton->setEnabled(running);
|
|
ui->startButton->setText(paused ? tr("继续") :
|
|
state == Countdown::State::Finished ? tr("重新开始") : tr("开始"));
|
|
if (running) ui->statusLabel->setText(tr("正在计时"));
|
|
else if (paused) ui->statusLabel->setText(tr("已暂停 · 点击“继续”接着计时"));
|
|
else if (state == Countdown::State::Finished)
|
|
ui->statusLabel->setText(tr("时间到!本轮计时已结束。"));
|
|
else ui->statusLabel->setText(m_countdown.duration() > 0
|
|
? tr("准备就绪 · 点击“开始”") : tr("请先设置大于 0 的时长。"));
|
|
if (previousState == Countdown::State::Running && state == Countdown::State::Finished
|
|
&& ui->soundCheck->isChecked())
|
|
QApplication::beep();
|
|
}
|
|
|