【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
? ? ? ? 用抽奖软件抽奖,是一种很常见的抽奖方式。特别是写这篇文章的时候,正好处于2023年12月31日,也是一年中最后一天。虽然今年过年晚一点,但是2到3个星期之后,基本上各家公司都会准备年终尾牙的活动了。年会上吃饭、表演节目这是标配,不过重头戏还是抽奖,这会极大调动员工的情绪,也会让员工更有归属感。
? ? ? ? 最近我们学习了QT程序,正好可以用QT设计一个简单的抽奖程序。
? ? ? ? 界面设计比较简单,主要就是3个label和2个按钮。label的作用,就是显示最终的中奖号码。2个按钮,一个是启动,一个是结束。启动按钮按下去的时候,3个数字开始跳动;结束按钮按下去的时候,数字停止跳动。最终留下来的数字,提示我们幸运儿就是这位朋友。
? ? ? ? 代码实现部分呢,有点类似于前面两篇文章的结合,同时增加一个随机数生成的功能。首先,两个按钮肯定需要绑定必要的按钮回调函数。其次,按钮按下去的时候,会触发定时器操作,这又相当于之前倒计时软件的设计。最后,因为每次显示的数据需要不同,所以还需要增加一个随机数生成的功能。要实现这些功能,我们看下头文件怎么设计,
#pragma once
#include <QtWidgets/QMainWindow>
#include <QTimer>
#include "ui_QtWidgetsApplication.h"
class QtWidgetsApplication : public QMainWindow
{
Q_OBJECT
public:
QtWidgetsApplication(QWidget *parent = nullptr);
~QtWidgetsApplication();
private:
Ui::QtWidgetsApplicationClass ui;
QTimer* p_timer;
int num;
int flag;
void display_number();
private slots:
void update();
void on_start_clicked();
void on_stop_clicked();
};
? ? ? ? 要实现前面需要的功能,还是要一步一步来开发。通常,我们先处理下构造函数和析构函数;随后处理按钮回调函数;最后处理定时器函数的部分。
#include <QRandomGenerator>
#include "QtWidgetsApplication.h"
QtWidgetsApplication::QtWidgetsApplication(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
//set font and color
QFont ft;
ft.setPointSize(20);
ui.label1->setFont(ft);
ui.label2->setFont(ft);
ui.label3->setFont(ft);
ui.label1->setStyleSheet("color: blue;");
ui.label2->setStyleSheet("color: blue;");
ui.label3->setStyleSheet("color: blue;");
#if 0 // set title in ui file
<property name = "windowTitle">
<string>LotteryDemo< / string>
< / property>
#endif
// initialize variable
num = 0;
flag = 0;
p_timer = NULL;
// connect button with function
connect(ui.pushButton1, &QPushButton::clicked, this, &QtWidgetsApplication::on_start_clicked);
connect(ui.pushButton2, &QPushButton::clicked, this, &QtWidgetsApplication::on_stop_clicked);
ui.pushButton1->setEnabled(true);
ui.pushButton2->setEnabled(false);
// display number here
display_number();
}
// destructor function
QtWidgetsApplication::~QtWidgetsApplication()
{
if (p_timer) delete p_timer;
}
// shou data here
void QtWidgetsApplication::display_number()
{
ui.label1->setText(QString::number(num / 100));
ui.label2->setText(QString::number((num % 100) / 10));
ui.label3->setText(QString::number(num % 10));
}
? ? ? ? 类的构造函数和析构函数非常重要,很多资源的申请和释放都是放在这里。当然,这里不仅包括了上面说的两个函数,还有一个display_number函数。大部分内容,都是之前文章已经讨论过的,这里不再赘述。唯一需要补充的,就是窗口标题的修改。目前为止,个人认为比较好的办法还是直接修改ui文件。
// start button callback function
void QtWidgetsApplication::on_start_clicked()
{
// release previous timer
if (p_timer)
{
delete p_timer;
p_timer = NULL;
}
// create a num, 0~999
num = QRandomGenerator::global()->bounded(1000);
// create timer
p_timer = new QTimer(this);
connect(p_timer, SIGNAL(timeout()), this, SLOT(update()));
p_timer->start(20); // 20 is interval
display_number();
// set button
ui.pushButton1->setEnabled(false);
ui.pushButton2->setEnabled(true);
}
// timeout callback function
void QtWidgetsApplication::update()
{
if (flag)
{
p_timer->stop();
delete p_timer;
p_timer = NULL;
flag = 0;
return;
}
num = QRandomGenerator::global()->bounded(1000);
display_number();
}
? ? ? ? 处理完了构造函数、析构函数,剩下来就是按钮的处理。start按钮的回调已经在构造函数中注册好了,当然stop也是一样。我们只需要实现具体的内容即可。因为是抽奖,它和倒计时不一样,所以定时器的创建和回调需要在按钮触发的时候才能添加,这和之前不太一样。当然函数中涉及到了随机数,引用QRandomGenerator处理一下即可。
// stop button callback function
void QtWidgetsApplication::on_stop_clicked()
{
flag = 1;
ui.pushButton1->setEnabled(true);
ui.pushButton2->setEnabled(false);
}
? ? ? ? 有开始就有结束。这里结束的处理方式就是flag置位,同时灰化一个按钮,高亮一个按钮。前面定时器回调的时候也用到了这个flag置位,即如果发现flag为1,立即停止定时器、删除定时器。
? ? ? ? 代码本身不复杂,直接拿过来编译和测试即可。编译无误的话,首先单击start,数字是否开始跳动;继续单击stop,数字是否不再跳动。如此操作几次,没有发现问题的话,就说明我们开发的代码是ok的,不然就要回去检查一下原因了,看看问题发生在什么地方。