Qt 自定义钟表组件,包括数字钟表和指针钟表
资源内容介绍
Qt 自定义钟表组件,包括数字钟表和指针钟表 #include "DigitalWatchWgt.h"#include <QTimer>#include <QTime>#include <QPainter>DigitalWatchWgt::DigitalWatchWgt(bool isShowSecond, QWidget *parent) : QWidget(parent), m_isShowSecond(isShowSecond){ initData();}DigitalWatchWgt::~DigitalWatchWgt(){ if (m_timer && m_timer->isActive()) { m_timer->stop(); }}void DigitalWatchWgt::setFixedSize(const QSize &size){ this->setFixedSize(size.width(), size.height());}void DigitalWatchWgt::setFixedSize(int w, int h){ qreal wid = 2 * m_border + m_margin.left() + m_margin.right(); qreal hgt = m_margin.top() + m_margin.bottom() + 2 * m_border; if (m_isShowSecond) { wid += 3 * m_numSpacing + 4 * m_colonSpacing + 2 * m_dotWid; } else { wid += 2 * m_numSpacing + 2 * m_colonSpacing + m_dotWid; } if (w > wid && h > hgt) { if (m_isShowSecond) { m_numSize.rwidth() = (w - wid) / kNumCount; } else { m_numSize.rwidth() = (w - wid) / 4; } m_numSize.rheight() = h - hgt; QWidget::setFixedSize(w, h); adjustPos(); calcLinePath(); }}void DigitalWatchWgt::setMargin(const QMargins &margin){ m_margin = margin; adaptSize();}void DigitalWatchWgt::setNumSpacing(int spacing){ m_numSpacing = spacing; adaptSize();}void DigitalWatchWgt::setColonSpacing(int spacing){ m_colonSpacing = spacing; adaptSize();}// 设置组件边框void DigitalWatchWgt::setBorder(qreal border){ m_border = border; adaptSize();}// 设置线条之间的偏移量void DigitalWatchWgt::setLineOffset(qreal offset){ m_lineOffset = offset > 0 ? offset : 0;}// 设置边框颜色void DigitalWatchWgt::setBorderColor(const QColor &borColor){ m_borColor = borColor;}// 设置组件圆角void DigitalWatchWgt::setBorderRadius(qreal borRadius){ m_borRadius = borRadius;}// 设置背景色void DigitalWatchWgt::setBackground(const QColor &bkg){ m_bkgColor = bkg;}// 设置数字显示的颜色void DigitalWatchWgt::setNumColor(const QColor &lightColor, const QColor &darkColor){ m_numLightColor = lightColor; m_numDarkColor = darkColor;}// 设置数字显示的尺寸void DigitalWatchWgt::setNumSize(const QSizeF &size){ m_numSize = size; adaptSize(); calcLinePath();}// 设置数字边框粗细void DigitalWatchWgt::setNumBorder(qreal border){ if (border < 0.5 * m_numSize.width() && border < 0.25 * m_numSize.height()) { m_numBorder = border; }}// 设置冒号点宽度void DigitalWatchWgt::setDotWidth(qreal dotWid){ m_dotWid = dotWid; adaptSize();}void DigitalWatchWgt::initData(){ m_margin = QMargins(12, 8, 12, 8); m_numSpacing = 12; m_colonSpacing = 12; m_border = 0; m_borRadius = 12; m_lineOffset = 3.0; m_bkgColor = Qt::transparent; m_numLightColor = QColor(255, 255, 255, 20); m_numDarkColor = QColor(12, 255, 12, 255); m_numSize = QSizeF(32.0, 64.0); m_numBorder = 8.0; m_dotWid = 8.0; m_timer = new QTimer(this); if (m_isShowSecond) { m_timer->setInterval(1000); } else { m_timer->setInterval(60000); } auto updateNumText = [this] { QString currTime = QTime::currentTime().toString("HHmmss"); if (kNumCount == currTime.length()) { for (int i = 0; i < kNumCount; ++i) { m_number[i].m_text = currTime.at(i); } } }; connect(m_timer, &QTimer::timeout, this, [=] { updateNumText(); update(); }); updateNumText(); m_timer->start();}void DigitalWatchWgt::adaptSize(){ int wid = m_margin.left() + m_margin.right() + static_cast<int>(2 * m_border); int hgt = m_margin.top() + m_margin.bottom() + m_numSize.height(); hgt += static_cast<int>(2 * m_border); if (m_isShowSecond) { wid += static_cast<int>(kNumCount * m_numSize.width() + 2 * m_dotWid); wid += 3 * m_numSpacing + 4 * m_colonSpacing; } else { wid += static_cast<int>(4 * m_numSize.width() + m_dotWid); wid += 2 * m_numSpacing + 2 * m_colonSpacing; } QWidget::setFixedSize(wid, hgt); adjustPos();}void DigitalWatchWgt::adjustPos(){ qreal xPos = m_border + m_margin.left(); qreal yPos = m_border + m_margin.top(); m_number[0].m_topX = xPos; m_number[0].m_topY = yPos; xPos += m_numSize.width() + m_numSpacing; m_number[1].m_topX = xPos; m_number[1].m_topY = yPos; xPos += m_numSize.width() + m_colonSpacing; m_rfColon[0] = QRectF(QPointF(xPos, yPos), QSizeF(m_dotWid, m_numSize.height())); xPos += m_dotWid + m_colonSpacing; m_number[2].m_topX = xPos; m_number[2].m_topY = yPos; xPos += m_numSize.width() + m_numSpacing; m_number[3].m_topX = xPos; m_number[3].m_topY = yPos; if (m_isShowSecond) { xPos += m_numSize.width() + m_colonSpacing; m_rfColon[1] = QRectF(xPos, yPos, m_dotWid, m_numSize.height()); xPos += m_dotWid + m_colonSpacing; m_number[4].m_topX = xPos; m_number[4].m_topY = yPos; xPos += m_numSize.width() + m_numSpacing; m_number[5].m_topX = xPos; m_number[5].m_topY = yPos; }}void DigitalWatchWgt::calcLinePath(){ qreal tempWid = 0.5 * m_numBorder; QPointF ptf(0, 0); QPainterPath path[kLineCount]; ptf.rx() += m_numBorder + m_lineOffset; path[0].moveTo(ptf); ptf.rx() = m_numSize.width() - m_numBorder - m_lineOffset; path[0].lineTo(ptf); ptf.rx() += tempWid; ptf.ry() += tempWid; path[0].lineTo(ptf); ptf.rx() -= tempWid; ptf.ry() += tempWid; path[0].lineTo(ptf); ptf.rx() = m_numBorder + m_lineOffset; path[0].lineTo(ptf); ptf.rx() -= tempWid; ptf.ry() -= tempWid; path[0].lineTo(ptf); ptf.rx() += tempWid; ptf.ry() -= tempWid; path[0].lineTo(ptf); ptf.setX(0); ptf.setY(m_numBorder + m_lineOffset); path[1].moveTo(ptf); ptf.rx() += tempWid; ptf.ry() -= tempWid; path[1].lineTo(ptf); ptf.rx() += tempWid; ptf.ry() += tempWid; path[1].lineTo(ptf); ptf.ry() = 0.5 * (m_numSize.height() - m_numBorder) - m_lineOffset; path[1].lineTo(ptf); ptf.rx() -= tempWid; ptf.ry() += tempWid; path[1].lineTo(ptf); ptf.rx() -= tempWid; ptf.ry() -= tempWid; path[1].lineTo(ptf); ptf.ry() = m_numBorder + m_lineOffset; path[1].lineTo(ptf); ptf.setX(m_numSize.width() - m_numBorder); ptf.setY(m_numBorder + m_lineOffset); path[2].moveTo(ptf); ptf.rx() += tempWid; ptf.ry() -= tempWid; path[2].lineTo(ptf); ptf.rx() += tempWid; ptf.ry() += tempWid; path[2].lineTo(ptf); ptf.ry() = 0.5 * (m_numSize.height() - m_numBorder) - m_lineOffset; path[2].lineTo(ptf); ptf.rx() -= tempWid; ptf.ry() += tempWid; path[2].lineTo(ptf); ptf.rx() -= tempWid; ptf.ry() -= tempWid; path[2].lineTo(ptf); ptf.ry() = m_numBorder + m_lineOffset; path[2].lineTo(ptf); ptf.setX(m_numBorder + m_lineOffset); ptf.setY(0.5 * (m_numSize.height() - m_numBorder)); path[3].moveTo(ptf); ptf.rx() = m_numSize.width() - m_numBorder - m_lineOffset; path[3].lineTo(ptf); ptf.rx() += tempWid; ptf.ry() += tempWid; path[3].lineTo(ptf); ptf.rx() -= tempWid; ptf.ry() += tempWid; path[3].lineTo(ptf); ptf.rx() = m_numBorder + m_lineOffset; path[3].lineTo(ptf); ptf.rx() -= tempWid; ptf.ry() -= tempWid; path[3].lineTo(ptf);