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();
    }
}

相关推荐

  1. Android:定义

    2023-12-13 10:10:03       29 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-13 10:10:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-13 10:10:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-13 10:10:03       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-13 10:10:03       20 阅读

热门阅读

  1. vb.net环境下的sqlitehelper分页解决

    2023-12-13 10:10:03       35 阅读
  2. Kubeadm 部署集群

    2023-12-13 10:10:03       34 阅读
  3. spark的宽依赖,窄依赖

    2023-12-13 10:10:03       41 阅读
  4. jupyter 局域网访问,无需密码验证

    2023-12-13 10:10:03       35 阅读
  5. media-ctl 生成拓扑和数据流图

    2023-12-13 10:10:03       40 阅读
  6. nodejs面试总结

    2023-12-13 10:10:03       32 阅读
  7. 有基础转Go语言学习笔记(3. 面向对象篇)

    2023-12-13 10:10:03       33 阅读
  8. 【PTA刷题】串右整理(代码+详解)

    2023-12-13 10:10:03       40 阅读
  9. Vue3 将el-table中的数据导出为excel并下载

    2023-12-13 10:10:03       40 阅读