Qt编写自定义控件实现抽奖转盘

 更新时间:2022年06月14日 11:42:55   作者:友善啊,朋友  
这篇文章主要为大家详细介绍了Qt编写自定义控件实现抽奖转盘,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了Qt自定义控件实现抽奖转盘的具体代码,供大家参考,具体内容如下

#ifndef LOTTERYTURNTABLEWIDGET_H
#define LOTTERYTURNTABLEWIDGET_H
 
#include <QWidget>
 
class LotteryTurntableWidget : public QWidget
{
    Q_OBJECT
    Q_PROPERTY(int rotate READ getRotate WRITE setRotate MEMBER painterRotate)
public:
    LotteryTurntableWidget(QWidget *parent = nullptr);
    ~LotteryTurntableWidget()override;
    int getRotate();
    void setRotate(int rotate);
 
protected:
    void paintEvent(QPaintEvent *event)override;
    void mousePressEvent(QMouseEvent *event)override;
    void mouseReleaseEvent(QMouseEvent *event)override;
 
private:
    QRect centerBtnRect;
    bool isPressCenterBtn{false};
    bool isRuning{false};
    int painterRotate{0};
    void onRotateFinished();
    QList<Qt::GlobalColor> colorList;
};
#endif // LOTTERYTURNTABLEWIDGET_H
#include "lotteryturntablewidget.h"
#include <QPainter>
#include <QPaintEvent>
#include <QPainterPath>
#include <QTime>
#include <QDebug>
#include <QRandomGenerator>
#include <QPropertyAnimation>
 
LotteryTurntableWidget::LotteryTurntableWidget(QWidget *parent)
    : QWidget(parent)
{
    setPalette(Qt::white);
    setMinimumSize(500,500);
 
    colorList << Qt::red << Qt::yellow << Qt::green << Qt::cyan << Qt::blue << Qt::magenta << Qt::darkGreen << Qt::darkCyan;
}
 
LotteryTurntableWidget::~LotteryTurntableWidget()
{
}
 
int LotteryTurntableWidget::getRotate()
{
    return painterRotate;
}
 
void LotteryTurntableWidget::setRotate(int rotate)
{
    painterRotate = rotate;
    update();
}
 
void LotteryTurntableWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing,true);  //反走样开启
    const auto rect = event->rect();
    auto radius = std::min(rect.width(),rect.height()) / 2 - 25;
 
    painter.save();
    painter.translate(rect.center()); //将坐标系的原点设置为(r,r)
 
    QPen pen;
    pen.setColor(QColor("#F0630B"));
    pen.setWidth(16);
    painter.setPen(pen);
    painter.drawEllipse(QPoint(0, 0), radius, radius);
 
    pen.setColor(QColor("#FF4500"));
    pen.setWidth(8);
    painter.setPen(pen);
    radius -= 8;
    painter.drawEllipse(QPoint(0, 0), radius, radius);
 
    pen.setColor(QColor("#B71606"));
    pen.setWidth(40);
    painter.setPen(pen);
    radius -= 24;
    painter.drawEllipse(QPoint(0, 0), radius, radius);
 
    painter.save();
    if(!isRuning)
    {
        painter.setPen(Qt::white);
        painter.setBrush(Qt::white);
    }
    for (int i = 0; i < 20; ++i)
    {
        painter.rotate(18.0);
        int smallEllipse;
        if(i % 2 == 0)
        {
            if(isRuning)
            {
                if(painterRotate % 2 == 0)
                {
                    painter.setPen(Qt::red);
                    painter.setBrush(Qt::red);
                }
                else
                {
                    painter.setPen(Qt::blue);
                    painter.setBrush(Qt::blue);
                }
            }
            smallEllipse = 15;
        }
        else
        {
            if(isRuning)
            {
                if(painterRotate % 2 == 0)
                {
                    painter.setPen(Qt::blue);
                    painter.setBrush(Qt::blue);
                }
                else
                {
                    painter.setPen(Qt::red);
                    painter.setBrush(Qt::red);
                }
            }
            smallEllipse = 10;
        }
        painter.drawEllipse(QPoint(radius, 0), smallEllipse, smallEllipse);
    }
    painter.restore();
 
    pen.setColor(QColor("#FFC228"));
    pen.setWidth(20);
    painter.setPen(pen);
    radius -= 30;
    painter.drawEllipse(QPoint(0, 0), radius, radius);
 
    radius -= 10;
    auto centerRect = QRect(-radius,-radius,radius * 2,radius * 2);
 
    painter.setPen(Qt::transparent);
    painter.save();
    painter.rotate(18.0 * painterRotate);
    for (int i = 0;i < 8;++i)
    {
        QPainterPath path;
        path.moveTo(0,0);
        path.arcTo(centerRect, 45 * i,45);
        path.closeSubpath();
        painter.fillPath(path,colorList[i]);
    }    
    painter.restore();
 
    QPainterPath trianglePath;//三角形
    QPolygon polygon;
    polygon.append(QPoint(0,-radius * 0.55));
    polygon.append(QPoint(-radius * 0.25,0));
    polygon.append(QPoint(radius * 0.25,0));
    trianglePath.addPolygon(polygon);
    painter.setBrush(QColor("#EEDAA2"));
    painter.drawPath(trianglePath);
 
    painter.setBrush(QColor("#FDFAEA"));
    radius = static_cast<int>(radius * 0.3);
    painter.drawEllipse(QPoint(0, 0), radius, radius);
 
    painter.setBrush(isPressCenterBtn ? QColor("#B91A0D").lighter() : QColor("#B91A0D"));//中间的按钮
    radius -= 2;
    painter.drawEllipse(QPoint(0, 0), radius, radius);
 
    centerBtnRect = QRect(rect.width() / 2 - radius,rect.height() / 2 - radius,radius * 2,radius * 2);
    painter.restore();
}
 
void LotteryTurntableWidget::mousePressEvent(QMouseEvent *event)
{
    if(isRuning)
    {
        QWidget::mousePressEvent(event);
        return;
    }
    QRegion ellipseRegion(centerBtnRect, QRegion::Ellipse);
    isPressCenterBtn = ellipseRegion.contains(event->pos());
    if(isPressCenterBtn)
    {
        isRuning = true;
 
        QPropertyAnimation *animation = new QPropertyAnimation(this, "rotate");
        animation->setEasingCurve(QEasingCurve::InOutCubic);
        animation->setDuration(3000);
        animation->setStartValue(0);
        animation->setEndValue(QRandomGenerator::global()->bounded(360) + 360 * 5);
        connect(animation, &QAbstractAnimation::finished, this, &LotteryTurntableWidget::onRotateFinished);
        animation->start(QAbstractAnimation::DeleteWhenStopped);
        update();
    }
    QWidget::mousePressEvent(event);
}
 
void LotteryTurntableWidget::mouseReleaseEvent(QMouseEvent *event)
{
    if(isPressCenterBtn)
    {
        isPressCenterBtn = false;
        update();
    }
    QWidget::mouseReleaseEvent(event);
}
 
void LotteryTurntableWidget::onRotateFinished()
{
    isRuning = false;
}

效果:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 详解C++中的指针结构体数组以及指向结构体变量的指针

    详解C++中的指针结构体数组以及指向结构体变量的指针

    这篇文章主要介绍了C++中的指针结构体数组以及指向结构体变量的指针的用法,是C++入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09
  • C++ 线段树原理与实现示例详解

    C++ 线段树原理与实现示例详解

    这篇文章主要为大家介绍了C++ 线段树原理与实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • C++中vector容器的常用操作方法实例总结

    C++中vector容器的常用操作方法实例总结

    vector容器一般被用作创建动态数组,动态数组就像Python中的list结构一样,可以比普通数组拥有更丰富操作方法,下面就为大家整理了一些最常用的操作:
    2016-05-05
  • 浅谈C++内存分配及变长数组的动态分配

    浅谈C++内存分配及变长数组的动态分配

    下面小编就为大家带来一篇浅谈C++内存分配及变长数组的动态分配。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09
  • C++ QT QThread启动、停止、暂停和恢复的实现

    C++ QT QThread启动、停止、暂停和恢复的实现

    本文主要介绍了C++ QT QThread启动、停止、暂停和恢复的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • C++双线程调用网络摄像头与多线程调用多摄像头同步执行方法详细讲解

    C++双线程调用网络摄像头与多线程调用多摄像头同步执行方法详细讲解

    这篇文章主要介绍了C++双线程调用网络摄像头与多线程调用多摄像头同步执行方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-11-11
  • 详解进程同步与互斥机制

    详解进程同步与互斥机制

    进程同步是一个操作系统级别的概念,是在多道程序的环境下,存在着不同的制约关系,为了协调这种互相制约的关系,实现资源共享和进程协作,从而避免进程之间的冲突,引入了进程同步
    2021-06-06
  • C语言学习之指针知识总结

    C语言学习之指针知识总结

    想突破C语言的学习,对指针的掌握是非常重要的,本文为大家总结了C语言中指针的相关知识点,文中的示例代码讲解详细,感兴趣的可以学习一下
    2022-07-07
  • 解析如何在C语言中调用shell命令的实现方法

    解析如何在C语言中调用shell命令的实现方法

    本篇文章是对如何在C语言中调用shell命令的方法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C语言利用UDP实现群聊聊天室的示例代码

    C语言利用UDP实现群聊聊天室的示例代码

    UDP是一个轻量级、不可靠、面向数据报的、无连接的传输层协议,多用于可靠性要求不严格,不是非常重要的传输,如直播、视频会议等等。本文将利用UDP实现简单的群聊聊天室,感兴趣的可以了解一下
    2022-08-08

最新评论