最近在整理QT图形界面开发的教学案例时,发现时钟应用是个非常好的入门项目。它不仅涵盖了QT绘图系统的核心功能,还能帮助初学者理解事件驱动编程的精髓。这个项目只需要基础的C++知识和QT开发环境,就能实现一个带有时针、分针和秒针的动态时钟。
推荐使用QT 5.15或更高版本,这是目前最稳定的LTS版本。安装时务必勾选以下组件:
注意:如果只是做基础绘图练习,可以跳过Qt Charts模块的安装,但建议保留以备后续扩展使用。
在Qt Creator中新建项目时选择:
首先在AnalogClock类中重写paintEvent方法:
cpp复制void AnalogClock::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
// 后续绘图代码将写在这里
}
关键参数说明:
为了绘图方便,我们需要建立以时钟中心为原点的坐标系:
cpp复制// 在paintEvent方法内添加
int side = qMin(width(), height());
painter.translate(width() / 2, height() / 2);
painter.scale(side / 200.0, side / 200.0);
这个转换实现了:
先绘制基本的圆形表盘:
cpp复制// 绘制外圆
painter.setPen(Qt::NoPen);
painter.setBrush(QColor(240, 240, 240));
painter.drawEllipse(QPoint(0, 0), 90, 90);
// 绘制刻度
painter.setPen(QPen(Qt::black, 2));
for (int i = 0; i < 60; ++i) {
if (i % 5 == 0) {
painter.drawLine(0, -80, 0, -70); // 小时刻度
} else {
painter.drawLine(0, -80, 0, -75); // 分钟刻度
}
painter.rotate(6.0); // 每分钟6度
}
在类中添加时间更新方法:
cpp复制void AnalogClock::updateTime()
{
QTime time = QTime::currentTime();
m_hour = time.hour();
m_minute = time.minute();
m_second = time.second();
update(); // 触发重绘
}
cpp复制// 时针
painter.save();
painter.rotate(30.0 * (m_hour + m_minute / 60.0));
painter.setPen(QPen(Qt::blue, 4));
painter.drawLine(0, 0, 0, -50);
painter.restore();
// 分针
painter.save();
painter.rotate(6.0 * (m_minute + m_second / 60.0));
painter.setPen(QPen(Qt::green, 3));
painter.drawLine(0, 0, 0, -70);
painter.restore();
// 秒针
painter.save();
painter.rotate(6.0 * m_second);
painter.setPen(QPen(Qt::red, 1));
painter.drawLine(0, 0, 0, -80);
painter.restore();
关键点说明:
在构造函数中添加:
cpp复制QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &AnalogClock::updateTime);
timer->start(1000); // 1秒刷新一次
对于高刷新率需求,可以:
通过Q_PROPERTY定义可动态修改的属性:
cpp复制Q_PROPERTY(QColor hourHandColor READ hourHandColor WRITE setHourHandColor)
在表盘周围添加数字小时标记:
cpp复制QFont font;
font.setPointSize(12);
painter.setFont(font);
for (int i = 1; i <= 12; ++i) {
int angle = 30 * i;
int x = 65 * qSin(angle * M_PI / 180);
int y = -65 * qCos(angle * M_PI / 180);
painter.drawText(x - 10, y + 5, 20, 20,
Qt::AlignCenter, QString::number(i));
}
现象:秒针移动不流畅,每秒钟跳动一次
解决方案:
解决方法:
cpp复制setAttribute(Qt::WA_TranslucentBackground);
setAttribute(Qt::WA_NoSystemBackground);
setAttribute(Qt::WA_HighDpiScaling);
确保所有QObject派生类都正确设置了parent,特别是:
这个时钟项目虽然基础,但涵盖了QT开发的多个核心概念。我在实际教学中发现,通过不断迭代完善这个案例,学员能够循序渐进地掌握QT开发的精髓。建议初学者可以先实现基本功能,再逐步添加扩展特性。