- 前言:
- 问题代码段:
- 解决方法代码段:
- 源码:
- 头文件:luckward.h
- UI文件:
- 主函数:main.cpp
- 实现文件:luckward.cpp
- ui界面布局样式:
- 效果图
问题代码段:本文简述:代码中有点小bug(已经粗暴解决),不提倡所有这类型bug都这样解决
问题描述:由于超时信号造成槽函数形成了死循环,也没啥好的方案去替换。
//问题根源
connect(&rtTimer, SIGNAL(timeout()), this, SLOT(rtTimeoutSlot()));//调用超时信号,计时旋转
//死循环部分
void LuckWard::rtTimeoutSlot(){
rotationAngle++;//旋转因子
if ((rotationAngle - randNumber) == 90)//当rotationAngle - randNumber==90°
{
rtTimer.setInterval(10);//减速到10毫秒
}
else if ((rotationAngle - randNumber) == 180)//当rotationAngle - randNumber==180°
{
rtTimer.setInterval(15);//减速到15毫秒
}
else if ((rotationAngle - randNumber) == 270)//当rotationAngle - randNumber==270°
{
rtTimer.setInterval(20);//减速到20毫秒
}
else if ((rotationAngle - randNumber) == 360)//当rotationAngle - randNumber==360°
{
rotationAngle--;//停下来
i++;//(PS:由于此处不知道为啥进入了死循环,只能加一个变量进行判断)
if (i == 1)//判断是否是第一次
{
emit luckOverSignal();//利用信号调用结束弹窗
}
}
update();//更新数据
}
解决方法代码段:
解决方法:在死循环内添加了一个全局函数进行计数,判断是否是第一次。从而调用结束信号,弹出窗口。
头文件处添加一个全局变量:
private: Ui::LuckWardClass ui; int i = 0; //记录变量
实现文件处添加一个“if”进行判断
//void LuckWard::rtTimeoutSlot()处代码段
else if ((rotationAngle - randNumber) == 360)//当rotationAngle - randNumber==360°
{
rotationAngle--;//停下来
//解决方法:
i++;//(PS:由于此处不知道为啥进入了死循环,只能加一个变量进行判断)
if (i == 1)//判断是否是第一次
{
emit luckOverSignal();//利用信号调用结束弹窗
}
}
源码:
头文件:luckward.h
#pragma once #includeUI文件:#include "ui_luckward.h" #include #include #include #include #include #include class LuckWard : public QWidget { Q_OBJECT public: LuckWard(QWidget *parent = Q_NULLPTR); //重载绘制事件 void paintEvent(QPaintEvent *ev); //重载鼠标按下事件 void mousePressEvent(QMouseEvent *ev); public slots: //计时旋转函数 void rtTimeoutSlot(); //转盘开始旋转函数 void luckStartSlot(); //转盘结束旋转函数 void luckOverSlot(); signals: //转盘开始旋转信号 void luckStartSignal(); //转盘结束信号 void luckOverSignal(); private: Ui::LuckWardClass ui; int i = 0; //记录变量 QPainter rotationPainter; //绘画转盘 int rotationAngle; //旋转角度 int randNumber; //随机数 int EndNumber; //结束数值 QTimer rtTimer; //旋转速度 QPainter pointPainter; //绘画箭头与钉子 };
#ifndef UI_LUCKWARD_H #define UI_LUCKWARD_H #include主函数:main.cpp#include #include #include #include #include QT_BEGIN_NAMESPACE class Ui_LuckWardClass { public: void setupUi(QWidget *LuckWardClass) { if (LuckWardClass->objectName().isEmpty()) LuckWardClass->setObjectName(QStringLiteral("LuckWardClass")); LuckWardClass->resize(400, 400); LuckWardClass->setMinimumSize(QSize(400, 400)); LuckWardClass->setMaximumSize(QSize(400, 400)); retranslateUi(LuckWardClass); QMetaObject::connectSlotsByName(LuckWardClass); } // setupUi void retranslateUi(QWidget *LuckWardClass) { LuckWardClass->setWindowTitle(QApplication::translate("LuckWardClass", "LuckWard", Q_NULLPTR)); } // retranslateUi }; namespace Ui { class LuckWardClass: public Ui_LuckWardClass {}; } // namespace Ui QT_END_NAMESPACE #endif // UI_LUCKWARD_H
#include "luckward.h" #include实现文件:luckward.cppint main(int argc, char *argv[]) { QApplication a(argc, argv); LuckWard w; w.show(); return a.exec(); }
#include "luckward.h"
LuckWard::LuckWard(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
connect(&rtTimer, SIGNAL(timeout()), this, SLOT(rtTimeoutSlot()));//调用超时信号,计时旋转
connect(this, SIGNAL(luckStartSignal()), this, SLOT(luckStartSlot()));//用luckStartSignal()发出的信号使转盘开始旋转
connect(this, SIGNAL(luckOverSignal()), this, SLOT(luckOverSlot()));//用luckOverSignal()发出的信号使转盘结束后弹窗
}
void LuckWard::paintEvent(QPaintEvent *ev)
{
//绘制转盘
rotationPainter.begin(this);//开始绘画
rotationPainter.setRenderHint(QPainter::SmoothPixmapTransform);//抗锯齿化
rotationPainter.translate(200, 200);//修改图片中心点
rotationPainter.rotate(rotationAngle);//使图片旋转30°
rotationPainter.drawPixmap(-200, -200, 400, 400, QPixmap("luck.png"));//添加图片
rotationPainter.end();//结束绘画
//绘制箭头
pointPainter.begin(this);//开始绘画
pointPainter.setRenderHint(QPainter::SmoothPixmapTransform);
pointPainter.translate(200, 200);//设置绘制坐标位置
static const QPoint point[4] = { QPoint(0, 18), QPoint(20, 0), QPoint(0, -100), QPoint(-20, 0) };//绘制路径
pointPainter.setBrush(QColor(Qt::blue));//设置箭头颜色
pointPainter.drawPolygon(point, 4);
//绘制钉子(处于中间点)
QRect rectanle(-7, -7, 14, 18); //设置绘制坐标位置
pointPainter.setBrush(QColor(Qt::yellow));//设置钉子颜色
pointPainter.drawEllipse(rectanle);//绘制椭圆形
pointPainter.end();//结束绘画
}
void LuckWard::rtTimeoutSlot()
{
rotationAngle++;//旋转因子
if ((rotationAngle - randNumber) == 90)//当rotationAngle - randNumber==90°
{
rtTimer.setInterval(10);//减速到10毫秒
}
else if ((rotationAngle - randNumber) == 180)//当rotationAngle - randNumber==180°
{
rtTimer.setInterval(15);//减速到15毫秒
}
else if ((rotationAngle - randNumber) == 270)//当rotationAngle - randNumber==270°
{
rtTimer.setInterval(20);//减速到20毫秒
}
else if ((rotationAngle - randNumber) == 360)//当rotationAngle - randNumber==360°
{
rotationAngle--;//停下来
i++;//(PS:由于此处不知道为啥进入了死循环,只能加一个变量进行判断)
if (i == 1)//判断是否是第一次
{
emit luckOverSignal();//利用信号调用结束弹窗
}
}
update();//更新数据
}
void LuckWard::mousePressEvent(QMouseEvent *ev)
{
if (ev->button() == Qt::LeftButton)//判断是否鼠标左键按下
{
qDebug() << "LeftButton Press" << ev->pos();//打印按下的位置
//判断是否在此范围内按下鼠标左键(x(180,220),y(216,130))
if (ev->pos().x() > 180 && ev->pos().x() < 220 && ev->pos().y()<216 && ev->pos().y()>130)
{
emit luckStartSignal();
}
}
}
void LuckWard::luckStartSlot()
{
rtTimer.setInterval(50);//设置旋转速度为50毫秒
rotationAngle = 1;//初始化旋转角为1
qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));//初始化随机数
randNumber = qrand() % 360 + 180; //设置随机数取值180 - >360之间
rtTimer.start(1);//定时器开始
}
void LuckWard::luckOverSlot()
{
qDebug() << "rotationAngle The Angle" << EndNumber;
if (EndNumber>0)
{
QMessageBox::information(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("恭喜您!中奖了"), QStringLiteral("确定"));
}
}
ui界面布局样式:
效果图



