Qt自帶的示例中有一個是關於時鐘,演示了如何用QPainter的轉換和縮放特性來繪制自定義部件。
其中主要包含了時針、分針的繪制,並不包含秒針。下面,我們在原示例的基礎上進行擴展。
由於時鐘是妙級更新的,所以我們需要定時刷新,時鐘則使用之前講過的QPainter 2D圖形來進行繪制。
首先,我們構造一個定時器QTimer,連接其超時信號timeout()到槽函數update(),當調用update()時,系統會自動通知當前界面進行重繪(paintEvent())。
MainWindow::MainWindow(QWidget *parent)
: CustomWindow(parent)
{
...
// 構造定時器,設置超時為1秒
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(1000);
...
}
重寫paintEvent(),用於繪制時鐘。
void MainWindow::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
// 時針、分針、秒針位置 - 多邊形
static const QPoint hourHand[3] = {
QPoint(7, 8),
QPoint(-7, 8),
QPoint(0, -30)
};
static const QPoint minuteHand[3] = {
QPoint(7, 8),
QPoint(-7, 8),
QPoint(0, -65)
};
static const QPoint secondHand[3] = {
QPoint(7, 8),
QPoint(-7, 8),
QPoint(0, -80)
};
// 時針、分針、秒針顏色
QColor hourColor(127, 0, 120);
QColor minuteColor(0, 127, 127, 120);
QColor secondColor(0, 160, 230, 120);
int side = qMin(width(), height());
QTime time = QTime::currentTime();
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
// 平移坐標系原點至中心點
painter.translate(width() / 2, height() / 2);
// 縮放
painter.scale(side / 200.0, side / 200.0);
// 繪制時針
painter.setPen(Qt::NoPen);
painter.setBrush(hourColor);
painter.save();
// 每圈360° = 12h 即:旋轉角度 = 小時數 * 30°
painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0)));
painter.drawConvexPolygon(hourHand, 3);
painter.restore();
painter.setPen(hourColor);
// 繪制小時線 (360度 / 12 = 30度)
for (int i = 0; i < 12; ++i) {
painter.drawLine(88, 0, 96, 0);
painter.rotate(30.0);
}
// 繪制分針
painter.setPen(Qt::NoPen);
painter.setBrush(minuteColor);
painter.save();
// 每圈360° = 60m 即:旋轉角度 = 分鐘數 * 6°
painter.rotate(6.0 * (time.minute() + time.second() / 60.0));
painter.drawConvexPolygon(minuteHand, 3);
painter.restore();
painter.setPen(minuteColor);
// 繪制分鐘線 (360度 / 60 = 6度)
for (int j = 0; j < 60; ++j) {
if ((j % 5) != 0)
painter.drawLine(92, 0, 96, 0);
painter.rotate(6.0);
}
// 繪制秒針
painter.setPen(Qt::NoPen);
painter.setBrush(secondColor);
painter.save();
// 每圈360° = 60s 即:旋轉角度 = 秒數 * 6°
painter.rotate(6.0 * time.second());
painter.drawConvexPolygon(secondHand, 3);
painter.restore();
}
好了,注釋寫的很清楚了,就不多做講解了,如果要做一個應用,可以自己實現一些設置指針、表盤樣式外觀的一些接口。