Qt繪制時(shí)鐘效果
簡(jiǎn)述
QPainter 提供了 2D 繪圖的常用操作,QTimer 提供了定時(shí)器功能,將兩者相結(jié)合,可以做出很多的自定義特效繪制。
下面,來實(shí)現(xiàn)一個(gè)每天都要接觸的東西 - 時(shí)鐘。包含了常見的所有功能:時(shí)針、分針、秒針。
實(shí)現(xiàn)方式
由于時(shí)鐘是妙級(jí)更新的,所以我們需要定時(shí)刷新,時(shí)鐘本身則使用之前講過的 QPainter 來進(jìn)行繪制。
使用 QTimer 定時(shí)刷新,設(shè)置超時(shí)時(shí)間為 1000 毫秒(1 秒)。
繪制時(shí)鐘,通過 paintEvent() 實(shí)現(xiàn),包括:時(shí)針、分針、秒針、及面板、表盤等。
繪制小時(shí)對(duì)應(yīng)的文本,文本區(qū)域通過 textRectF() 計(jì)算。
示例
效果

源碼
首先,我們構(gòu)造一個(gè)定時(shí)器 QTimer,連接其超時(shí)信號(hào) timeout() 到槽函數(shù) update(),當(dāng)調(diào)用 update() 時(shí),系統(tǒng)會(huì)自動(dòng)通知當(dāng)前界面進(jìn)行重繪(paintEvent())。
ClockWidget::ClockWidget(QWidget *parent)
: QWidget(parent)
{
...
// 構(gòu)造定時(shí)器,設(shè)置超時(shí)為 1 秒
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(1000);
...
}
實(shí)現(xiàn)一個(gè)用于獲取文本區(qū)域的接口:
QRectF ClockWidget::textRectF(double radius, int pointSize, double angle)
{
QRectF rectF;
rectF.setX(radius*qCos(angle*M_PI/180.0) - pointSize*2);
rectF.setY(radius*qSin(angle*M_PI/180.0) - pointSize/2.0);
rectF.setWidth(pointSize*4);
rectF.setHeight(pointSize);
return rectF;
}
注意:這里,textRectF() 主要用于獲取小時(shí)對(duì)應(yīng)的文本區(qū)域。
重寫 paintEvent(),用于繪制時(shí)鐘。
void ClockWidget::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
// 時(shí)針、分針、秒針位置 - 多邊形
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)
};
// 時(shí)針、分針、秒針顏色
QColor hourColor(200, 100, 0, 200);
QColor minuteColor(0, 127, 127, 150);
QColor secondColor(0, 160, 230, 150);
int side = qMin(width(), height());
QTime time = QTime::currentTime();
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
// 平移坐標(biāo)系原點(diǎn)至中心點(diǎn)
painter.translate(width() / 2, height() / 2);
// 縮放
painter.scale(side / 200.0, side / 200.0);
// 繪制時(shí)針
painter.setPen(Qt::NoPen);
painter.setBrush(hourColor);
painter.save();
// 每圈360° = 12h 即:旋轉(zhuǎn)角度 = 小時(shí)數(shù) * 30°
painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0)));
painter.drawConvexPolygon(hourHand, 3);
painter.restore();
painter.setPen(hourColor);
// 繪制小時(shí)線 (360度 / 12 = 30度)
for (int i = 0; i < 12; ++i) {
painter.drawLine(88, 0, 96, 0);
painter.rotate(30.0);
}
int radius = 100;
QFont font = painter.font();
font.setBold(true);
painter.setFont(font);
int pointSize = font.pointSize();
// 繪制小時(shí)文本
int nHour = 0;
for (int i = 0; i < 12; ++i) {
nHour = i + 3;
if (nHour > 12)
nHour -= 12;
painter.drawText(textRectF(radius*0.8, pointSize, i * 30), Qt::AlignCenter, QString::number(nHour));
}
// 繪制分針
painter.setPen(Qt::NoPen);
painter.setBrush(minuteColor);
painter.save();
// 每圈360° = 60m 即:旋轉(zhuǎn)角度 = 分鐘數(shù) * 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 即:旋轉(zhuǎn)角度 = 秒數(shù) * 6°
painter.rotate(6.0 * time.second());
painter.drawConvexPolygon(secondHand, 3);
painter.restore();
}
好了,注釋寫的很清楚了,就不多做講解了,如果要做一個(gè)應(yīng)用,可以自己實(shí)現(xiàn)一些設(shè)置指針、表盤樣式外觀的一些接口。
注意:網(wǎng)上很多文本都是在旋轉(zhuǎn)之后繪制上去的,效果并不好(6 顯示的是 9),所以請(qǐng)避免這一點(diǎn)!
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- QT實(shí)現(xiàn)動(dòng)態(tài)時(shí)鐘
- Qt實(shí)現(xiàn)指針式時(shí)鐘 Qt實(shí)現(xiàn)動(dòng)態(tài)時(shí)鐘
- Qt實(shí)現(xiàn)簡(jiǎn)易時(shí)鐘
- Qt繪制簡(jiǎn)單時(shí)鐘
- Qt編程實(shí)現(xiàn)小時(shí)鐘
- Qt設(shè)計(jì)時(shí)鐘效果
- QT實(shí)現(xiàn)簡(jiǎn)單時(shí)鐘效果
- Python+Pyqt實(shí)現(xiàn)簡(jiǎn)單GUI電子時(shí)鐘
- QTimer與QTime實(shí)現(xiàn)電子時(shí)鐘
- Qt實(shí)現(xiàn)簡(jiǎn)單動(dòng)態(tài)時(shí)鐘
相關(guān)文章
C語言結(jié)構(gòu)體嵌套與對(duì)齊超詳細(xì)講解
這篇文章主要介紹了C語言結(jié)構(gòu)體嵌套與對(duì)齊,C語言中結(jié)構(gòu)體是一種構(gòu)造類型,和數(shù)組、基本數(shù)據(jù)類型一樣,可以定義指向該種類型的指針。結(jié)構(gòu)體指針的定義類似其他基本數(shù)據(jù)類型的定義2022-12-12
C語言當(dāng)函數(shù)執(zhí)行成功時(shí)return1還是0
本文主要介紹了C語言當(dāng)函數(shù)執(zhí)行成功時(shí)return1還是0,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
對(duì)C++默認(rèn)構(gòu)造函數(shù)的一點(diǎn)重要說明
下面小編就為大家?guī)硪黄獙?duì)C++默認(rèn)構(gòu)造函數(shù)的一點(diǎn)重要說明。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-12-12
C++中const的實(shí)現(xiàn)機(jī)制深入分析
C語言以及C++語言中的const究竟表示什么?其具體的實(shí)現(xiàn)機(jī)制又是如何實(shí)現(xiàn)的呢?本文將對(duì)這兩個(gè)問題進(jìn)行一些分析,需要了解的朋友可以參考下2012-12-12

