您好,登錄后才能下訂單哦!
這篇文章主要講解了Qt繪制時鐘的代碼解析,內容清晰明了,對此有興趣的小伙伴可以學習一下,相信大家閱讀完之后會有幫助。
簡述
QPainter 提供了 2D 繪圖的常用操作,QTimer 提供了定時器功能,將兩者相結合,可以做出很多的自定義特效繪制。
下面,來實現一個每天都要接觸的東西 - 時鐘。包含了常見的所有功能:時針、分針、秒針。
實現方式
由于時鐘是妙級更新的,所以我們需要定時刷新,時鐘本身則使用之前講過的 QPainter 來進行繪制。
使用 QTimer 定時刷新,設置超時時間為 1000 毫秒(1 秒)。
繪制時鐘,通過 paintEvent() 實現,包括:時針、分針、秒針、及面板、表盤等。
繪制小時對應的文本,文本區域通過 textRectF() 計算。
示例
效果
源碼
首先,我們構造一個定時器 QTimer,連接其超時信號 timeout() 到槽函數 update(),當調用 update() 時,系統會自動通知當前界面進行重繪(paintEvent())。
ClockWidget::ClockWidget(QWidget *parent) : QWidget(parent) { ... // 構造定時器,設置超時為 1 秒 QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(update())); timer->start(1000); ... }
實現一個用于獲取文本區域的接口:
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() 主要用于獲取小時對應的文本區域。
重寫 paintEvent(),用于繪制時鐘。
void ClockWidget::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(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); // 平移坐標系原點至中心點 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); } int radius = 100; QFont font = painter.font(); font.setBold(true); painter.setFont(font); int pointSize = font.pointSize(); // 繪制小時文本 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 即:旋轉角度 = 分鐘數 * 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(); }
好了,注釋寫的很清楚了,就不多做講解了,如果要做一個應用,可以自己實現一些設置指針、表盤樣式外觀的一些接口。
注意:網上很多文本都是在旋轉之后繪制上去的,效果并不好(6 顯示的是 9),所以請避免這一點!
看完上述內容,是不是對Qt繪制時鐘的代碼解析有進一步的了解,如果還想學習更多內容,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。