Qt 自定义钟表组件,包括数字钟表和指针钟表
立即下载
资源介绍:
Qt 自定义钟表组件,包括数字钟表和指针钟表
#include "DigitalWatchWgt.h"
#include
#include
#include
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(2 * m_border);
int hgt = m_margin.top() + m_margin.bottom() + m_numSize.height();
hgt += static_cast(2 * m_border);
if (m_isShowSecond) {
wid += static_cast(kNumCount * m_numSize.width() + 2 * m_dotWid);
wid += 3 * m_numSpacing + 4 * m_colonSpacing;
} else {
wid += static_cast(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);