Qt编写自定义控件:时间选择控件

#include "rotateedittimewidget.h"
#include <QPainter>
#include <QDateTime>
#include <QDebug>
#include <QMouseEvent>

struct RotateEditTimeWidgetPrivate
{
    bool isEditHour{true};
    QRect handleRect;
    bool isPress{false};
    int angle{0};
    int hour{0};
    int minute{0};
    QRect textRect;
};

RotateEditTimeWidget::RotateEditTimeWidget(QWidget *parent)
    : QWidget(parent)
{
    d_ptr = new RotateEditTimeWidgetPrivate;
    auto time = QDateTime::currentDateTime().time();
    d_ptr->hour = time.hour();
    d_ptr->minute = time.minute();
    d_ptr->angle = d_ptr->hour * 15;
}

RotateEditTimeWidget::~RotateEditTimeWidget()
{
    delete d_ptr;
}

void RotateEditTimeWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing,true);
    painter.setRenderHints(QPainter::TextAntialiasing);

    auto thisRect = rect();
    auto side = qMin(thisRect.width(), thisRect.height()) / 2 - 5;

    painter.save();
    painter.translate(thisRect.center());
    painter.setBrush(Qt::transparent);
    painter.setPen(QPen(Qt::red,3));
    painter.drawEllipse(QPoint(0,0),side ,side);
    painter.restore();

    {
        painter.save();

        QString time24 = QString("%1:%2").arg(d_ptr->hour, 2, 10, QLatin1Char('0')).arg(d_ptr->minute, 2, 10, QLatin1Char('0'));

        QFont font("Arial", 12);
        int fontSize = side / 5;
        font.setPointSize(fontSize);
        font.setBold(true);
        painter.setFont(font);

        d_ptr->textRect = painter.boundingRect(thisRect,Qt::AlignCenter,time24);
        QLinearGradient linearGradient(d_ptr->textRect.topLeft(),d_ptr->textRect.topRight());
        if(d_ptr->isEditHour)
        {
            linearGradient.setColorAt(0.0,Qt::blue);
            linearGradient.setColorAt(0.45,Qt::blue);
            linearGradient.setColorAt(0.46,Qt::black);
            linearGradient.setColorAt(0.6,Qt::black);
            linearGradient.setColorAt(1.0,Qt::black);
        }
        else
        {
            linearGradient.setColorAt(0.0,Qt::black);
            linearGradient.setColorAt(0.4,Qt::black);
            linearGradient.setColorAt(0.54,Qt::black);
            linearGradient.setColorAt(0.55,Qt::blue);
            linearGradient.setColorAt(1.0,Qt::blue);
        }

        painter.setPen(QPen(QBrush(linearGradient),3));

        painter.drawText(thisRect,Qt::AlignCenter,time24);
        painter.restore();
    }

    painter.save();
    painter.setBrush(QColor("#aae8e8e8"));
    painter.setPen(QPen(Qt::blue,3));

    painter.translate(thisRect.center());
    auto handleRectTemp_zeroRect_center = QPoint(0,-side * 0.8);
    QTransform transform;
    transform.rotate(d_ptr->angle);
    QPoint transform_p = transform.map(handleRectTemp_zeroRect_center);
    d_ptr->handleRect = QRect(transform_p - QPoint(side / 9,side /9),transform_p + QPoint(side / 9,side /9));
    painter.drawEllipse(d_ptr->handleRect);
    painter.restore();
}

void RotateEditTimeWidget::mousePressEvent(QMouseEvent *event)
{
    auto pos = event->pos();
    const auto & rect = d_ptr->textRect;
    if(rect.contains(pos))
    {
        if(QRect(rect.topLeft(),QSize(rect.width() * 0.4,rect.height())).contains(pos))
        {
            d_ptr->isEditHour = true;
            d_ptr->angle = d_ptr->hour * 15;
        }
        else if(QRect(rect.topLeft() + QPoint(rect.width() * 0.6,0),QSize(rect.width() * 0.4,rect.height())).contains(pos))
        {
            d_ptr->isEditHour = false;
            d_ptr->angle = d_ptr->minute * 6;
        }
        update();
    }
    else
    {
        auto temp = d_ptr->handleRect;
        auto thisRect = this->rect();
        temp.translate(thisRect.width() / 2,thisRect.height() / 2);

        if(temp.contains(pos))
        {
            d_ptr->isPress = true;
            update();
        }
    }
}

void RotateEditTimeWidget::mouseReleaseEvent(QMouseEvent *event)
{
    if(d_ptr->isPress)
    {
        d_ptr->isPress = false;
        update();
    }
}

void RotateEditTimeWidget::mouseMoveEvent(QMouseEvent *event)
{
    if(d_ptr->isPress)
    {
        auto pos = event->pos();
        auto rectCenterPos = rect().center();

        QLineF line1(rectCenterPos,QPoint(rectCenterPos.x(),0));
        QLineF line2(rectCenterPos,pos);
        d_ptr->angle = line2.angleTo(line1);
        if(d_ptr->isEditHour)
        {
            d_ptr->hour = d_ptr->angle / 15;
        }
        else
        {
            d_ptr->minute = d_ptr->angle / 6;
        }
        update();
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值