亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Qt繪制時鐘效果

 更新時間:2020年05月30日 09:07:11   作者:weixin_33695450  
這篇文章主要為大家詳細介紹了Qt繪制時鐘效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

簡述

QPainter 提供了 2D 繪圖的常用操作,QTimer 提供了定時器功能,將兩者相結合,可以做出很多的自定義特效繪制。

下面,來實現(xiàn)一個每天都要接觸的東西 - 時鐘。包含了常見的所有功能:時針、分針、秒針。

實現(xiàn)方式

由于時鐘是妙級更新的,所以我們需要定時刷新,時鐘本身則使用之前講過的 QPainter 來進行繪制。

使用 QTimer 定時刷新,設置超時時間為 1000 毫秒(1 秒)。
繪制時鐘,通過 paintEvent() 實現(xiàn),包括:時針、分針、秒針、及面板、表盤等。
繪制小時對應的文本,文本區(qū)域通過 textRectF() 計算。

示例

效果

源碼

首先,我們構造一個定時器 QTimer,連接其超時信號 timeout() 到槽函數(shù) update(),當調(diào)用 update() 時,系統(tǒng)會自動通知當前界面進行重繪(paintEvent())。

ClockWidget::ClockWidget(QWidget *parent)
  : QWidget(parent)
{
  ...
 
  // 構造定時器,設置超時為 1 秒
  QTimer *timer = new QTimer(this);
  connect(timer, SIGNAL(timeout()), this, SLOT(update()));
  timer->start(1000);
  ...
}

實現(xiàn)一個用于獲取文本區(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() 主要用于獲取小時對應的文本區(qū)域。

重寫 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 即:旋轉(zhuǎn)角度 = 小時數(shù) * 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 即:旋轉(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();
}

好了,注釋寫的很清楚了,就不多做講解了,如果要做一個應用,可以自己實現(xiàn)一些設置指針、表盤樣式外觀的一些接口。

注意:網(wǎng)上很多文本都是在旋轉(zhuǎn)之后繪制上去的,效果并不好(6 顯示的是 9),所以請避免這一點!

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • 解決在Mac下直接解壓C++靜態(tài)庫出現(xiàn)的問題

    解決在Mac下直接解壓C++靜態(tài)庫出現(xiàn)的問題

    最近在研究C++的各種編譯構建過程,學習了一下cmake,gyp/ninja這些自動化構建工具后,想著自己試下用純命令行跑一遍編譯流程。在試圖把C++靜態(tài)庫編譯為動態(tài)庫的過程中遇到了棘手的問題,找了好久后發(fā)現(xiàn)是跟Mac平臺相關的,這里記錄一下,望對遇到類似問題的童鞋有幫助。
    2016-12-12
  • C++11之后的decltype類型指示符詳解

    C++11之后的decltype類型指示符詳解

    為了滿足這一要求,C++11?新標準引入了另一種類型說明符?decltype?,它的作用是選擇并返回操作數(shù)的數(shù)據(jù)類型,這篇文章主要介紹了C++11之后的decltype類型指示符,需要的朋友可以參考下
    2023-01-01
  • VS中scanf為何會報錯詳解

    VS中scanf為何會報錯詳解

    在我們剛使用vs時,在使用scanf函數(shù)時常會遇到報錯提醒,下面這篇文章主要給大家介紹了關于VS中scanf為何會報錯的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-02-02
  • C語言進程程序替換的實現(xiàn)詳解

    C語言進程程序替換的實現(xiàn)詳解

    為什么要進程替換?因為父進程創(chuàng)建出來的子進程和父進程擁有相同的代碼段,所以,子進程看到的代碼和父進程是一樣的。當我們想要讓子進程執(zhí)行不同的程序時候,就需要讓子進程調(diào)用進程程序替換的接口,從而讓子進程執(zhí)行不一樣的代碼
    2022-08-08
  • C++之談談構造函數(shù)的初始化列表

    C++之談談構造函數(shù)的初始化列表

    構造函數(shù)主要作用在于創(chuàng)建對象時為對象的成員屬性賦值,構造函數(shù)由編譯器自動調(diào)用,無須手動調(diào)用,這篇文章詳細介紹了構造函數(shù)的初始化列表,文章中有詳細的示例代碼,感興趣的同學可以參考閱讀
    2023-04-04
  • C++?vector與數(shù)組轉(zhuǎn)換寫入/讀出文件方式

    C++?vector與數(shù)組轉(zhuǎn)換寫入/讀出文件方式

    這篇文章主要介紹了C++?vector與數(shù)組轉(zhuǎn)換寫入/讀出文件方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • Qt實現(xiàn)編寫SMTP客戶端的示例詳解

    Qt實現(xiàn)編寫SMTP客戶端的示例詳解

    這篇文章主要介紹了如何通過Qt實現(xiàn)編寫SMTP客戶端,可以實現(xiàn)通過SMTP發(fā)送電子郵件(有文本,html,附件,內(nèi)聯(lián)文件等的MIME)。并支持SSL和SMTP身份驗證,感興趣的可以學習一下
    2022-11-11
  • C語言棧的表示與實現(xiàn)實例詳解

    C語言棧的表示與實現(xiàn)實例詳解

    這篇文章主要介紹了C語言棧的表示與實現(xiàn),對于數(shù)據(jù)結構與算法的研究有一定的借鑒價值,需要的朋友可以參考下
    2014-07-07
  • Cocos2d-x 3.x入門教程(二):Node節(jié)點類

    Cocos2d-x 3.x入門教程(二):Node節(jié)點類

    這篇文章主要介紹了Cocos2d-x 3.x入門教程(二):Node節(jié)點類,本文對Node節(jié)點類做了一個簡明講解及Node類提供的函數(shù)做了說明,需要的朋友可以參考下
    2014-11-11
  • C++可變參數(shù)函數(shù)的實現(xiàn)方法示例

    C++可變參數(shù)函數(shù)的實現(xiàn)方法示例

    這篇文章主要給大家介紹了關于C++可變參數(shù)函數(shù)的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12

最新評論