zoukankan      html  css  js  c++  java
  • Qt_Demo_2:实现猜字小游戏

    1  环境

    系统:windows 10

    代码编写运行环境:Qt Creator 4.4.1 (community)

    Github:https://github.com/zhengcixi/Qt_Demo/tree/master/GuessNum

    2  简介

    参考视频:https://www.bilibili.com/video/BV1XW411x7NU?p=35https://www.bilibili.com/video/BV1XW411x7NU?p=35

    参考博客:https://blog.csdn.net/fengge2018/article/details/106411326

    实现功能:一个猜字小游戏,系统随机产生一个4位数,在规定时间内,我们输入4位数进行匹配,如果相同,则赢了;不同且时间到了,则输了。

    赢了的实现效果如下:

    输了的实现效果如下:

    3  实现过程

    下面简单说明一下实现的过程:

    (1)先创建一个带ui的项目工程,主要包含了如下文件。

    (2)ui界面的设计

    我们进入widget.ui进行界面设计。使用QStackWidget来存放多个页面,包括以下4个页面:

    pageSet是我们刚开始运行时的页面,包含两个QLabel、一个QComboBox、两个QPushButton,如下图:

    pageGame是我们玩游戏时的页面,包含一个QProgressBar、一个QTextEdit、10个按钮,如下图:

    pageWin是胜利时显示的页面,就只包含一个QLabel组件:

    pageLose是输了的时候显示的页面,也只包含一个QLabel组件:

    (3)代码逻辑

    启动后,我们点击“进入游戏按钮”切换到pageGame,并读取出QComboBox中设置的倒计时时间,启动一个计数器开始计数,并生成一个四位数的随机数;

    然后我们输入数字按钮开始进行匹配,数字按钮的槽函数使用同一个,因为它们处理的逻辑是一样的;

    若我们输入的数字和随机数相同,则计数器停止计数,并切换到pageWin,启动另一个计时器,显示5s动画后,回到pageSet;

    若我们输入的数字和随机数不同,则判断其和随机数的大小,并给出对应的提示;

    若时间到了且我们没有猜出成功的答案,则切换到pageLose,启动另一个计时器,显示5s动画后,回到pageSet。

    (4)实现代码

    widget.h代码:

     1 #ifndef WIDGET_H
     2 #define WIDGET_H
     3 
     4 #include <QWidget>
     5 #include <QString>
     6 #include <QTimer>
     7 #include <QMovie>
     8 
     9 namespace Ui {
    10 class Widget;
    11 }
    12 
    13 //目的:实现一个猜字游戏
    14 //说明:
    15 //
    16 
    17 class Widget : public QWidget
    18 {
    19     Q_OBJECT
    20 
    21 public:
    22     explicit Widget(QWidget *parent = 0);
    23     ~Widget();
    24 
    25     //槽函数
    26     void on_PushButtonStart_clicked();
    27     void on_PushButtonQuit_clicked();
    28     void on_PushButtonRollback_clicked();
    29     void on_PushButtonNotice_clicked();
    30     void dealNum();
    31     void timerEvent(QTimerEvent *event);
    32 
    33 private:
    34     int gameTime;
    35     int gameTimerId;   //游戏定时器
    36     int loseTimerId;   //输了
    37     int winTimerId;    //赢了
    38     QString randStr;   //随机数
    39     QString resultStr; //结果数
    40     QMovie winMovie;   //赢了的动画
    41     QMovie loseMovie;  //输了的动画
    42 
    43 
    44 private:
    45     Ui::Widget *ui;
    46 };
    47 
    48 #endif // WIDGET_H
    View Code

    widget.cpp代码:

      1 #include "widget.h"
      2 #include "ui_widget.h"
      3 #include <QDebug>
      4 #include <QTime>
      5 #include <QMessageBox>
      6 
      7 Widget::Widget(QWidget *parent) :
      8     QWidget(parent),
      9     ui(new Ui::Widget)
     10 {
     11     ui->setupUi(this);
     12 
     13     //显示第一个页面,设置页面
     14     ui->stackedWidget->setCurrentWidget(ui->pageSet);
     15     //失败动画
     16     loseMovie.setFileName(":/new/prefix1/image/over.gif");
     17     ui->label_lose->setMovie(&loseMovie);//给标签设置动画
     18     ui->label_lose->setScaledContents(true);//让动画自动适应标签大小
     19     //胜利动画
     20     winMovie.setFileName(":/new/prefix1/image/win.gif");
     21     ui->label_win->setMovie(&winMovie);
     22     ui->label_win->setScaledContents(true);
     23 
     24     //启动游戏
     25     connect(ui->pushButton_enter, &QPushButton::clicked, this, &Widget::on_PushButtonStart_clicked);
     26     //退出游戏
     27     connect(ui->pushButton_quit,  &QPushButton::clicked, this, &Widget::close);
     28     //删除前一个数字
     29     connect(ui->pushButton_rollback, &QPushButton::clicked, this, &Widget::on_PushButtonRollback_clicked);
     30     //提示
     31     connect(ui->pushButton_notice, &QPushButton::clicked, this, &Widget::on_PushButtonNotice_clicked);
     32 
     33     //对数字按钮的处理使用同一个槽函数
     34     connect(ui->pushButton_0, &QPushButton::clicked, this, &Widget::dealNum);
     35     connect(ui->pushButton_1, &QPushButton::clicked, this, &Widget::dealNum);
     36     connect(ui->pushButton_2, &QPushButton::clicked, this, &Widget::dealNum);
     37     connect(ui->pushButton_3, &QPushButton::clicked, this, &Widget::dealNum);
     38     connect(ui->pushButton_4, &QPushButton::clicked, this, &Widget::dealNum);
     39     connect(ui->pushButton_5, &QPushButton::clicked, this, &Widget::dealNum);
     40     connect(ui->pushButton_6, &QPushButton::clicked, this, &Widget::dealNum);
     41     connect(ui->pushButton_7, &QPushButton::clicked, this, &Widget::dealNum);
     42     connect(ui->pushButton_8, &QPushButton::clicked, this, &Widget::dealNum);
     43     connect(ui->pushButton_9, &QPushButton::clicked, this, &Widget::dealNum);
     44 }
     45 
     46 void Widget::on_PushButtonStart_clicked()
     47 {
     48     //获取下拉框时间,并将字符串转换为整数
     49     gameTime = ui->comboBox->currentText().toInt();
     50     qDebug() << gameTime << "s";
     51 
     52     //切换到游戏界面
     53     ui->stackedWidget->setCurrentWidget(ui->pageGame);
     54 
     55     int num;
     56     //从0时0分0秒到现在的秒数为种子
     57     qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
     58     //调用全局的qsrand()函数生成随机数,对10000取余,保证位于10000的范围内
     59     while((num = qrand()%10000) < 999);
     60     randStr = QString::number(num);
     61     qDebug() << "randNum" << randStr;
     62 
     63     //设置进度条
     64     ui->progressBar->setMinimum(0); //最小值
     65     ui->progressBar->setMaximum(gameTime);  //最大值
     66     ui->progressBar->setValue(gameTime); //当前值
     67 
     68     //启动定时器
     69     gameTimerId = startTimer(1000);  //以1000ms为间隔
     70     resultStr.clear();
     71     ui->textEdit->clear();
     72 }
     73 
     74 void Widget::on_PushButtonRollback_clicked()
     75 {
     76     //退格按钮,删除最后一个数字
     77     if(resultStr.size() == 1) {
     78         resultStr.clear();
     79         ui->textEdit->clear();
     80     } else {
     81         resultStr.chop(1); //截断最后一位字符
     82         ui->textEdit->setText(resultStr);
     83     }
     84 }
     85 
     86 void Widget::on_PushButtonNotice_clicked()
     87 {
     88     //提示
     89     resultStr.clear();
     90     QString str = "正确答案为:" + randStr;
     91     ui->textEdit->setText(str);
     92 }
     93 
     94 void Widget::timerEvent(QTimerEvent *event)
     95 {
     96     if(event->timerId() == gameTimerId) {  //游戏时间
     97         gameTime--;
     98         //设置进度条
     99         ui->progressBar->setValue(gameTime); //当前值
    100         //时间到
    101         if(0 == gameTime) {
    102             //关闭定时器
    103             killTimer(gameTimerId);
    104             QMessageBox::information(this, "失败", "时间到了啊!!!");
    105             loseMovie.start();//启动动画
    106             //切换失败动画页面
    107             ui->stackedWidget->setCurrentWidget(ui->pageLose);
    108             loseTimerId = startTimer(5000); //启动定时器
    109         }
    110     } else if(event->timerId() == loseTimerId) {  //失败动画时间
    111         //停止动画,停止定时器,回到游戏设置页面
    112         loseMovie.stop();//停止动画
    113         killTimer(loseTimerId);  //停止定时器
    114         //切换到游戏设置页面
    115         ui->stackedWidget->setCurrentWidget(ui->pageSet);
    116     } else if(event->timerId() == winTimerId) {  //胜利动画时间
    117         winMovie.stop();//停止动画
    118         killTimer(winTimerId);  //停止定时器
    119         //切换到游戏设置页面
    120         ui->stackedWidget->setCurrentWidget(ui->pageSet);
    121     }
    122 }
    123 
    124 void Widget::dealNum()
    125 {
    126     //获取信号发送者
    127     QObject *mysender = sender();
    128     //转换为按钮类型
    129     QPushButton *pb = (QPushButton *)mysender;
    130     if (NULL != pb) {
    131         //获取按钮内容
    132         QString numStr = pb->text();
    133         resultStr += numStr;
    134         //数字不能以0开始
    135         if (resultStr.size() == 1 && resultStr=="0") {
    136             resultStr.clear();
    137         }
    138         //保证显示结果为4位
    139         if(resultStr.size() <= 4) {
    140             ui->textEdit->setText(resultStr);
    141             if (resultStr.size() == 4) {
    142                 if (resultStr > randStr) {
    143                     ui->textEdit->append("数字大了点!!!");
    144                 } else if (resultStr < randStr) {
    145                     ui->textEdit->append("数字小了点!!!");
    146                 } else {
    147                     ui->textEdit->append("恭喜你答对了!!!");
    148                     //停止定时器
    149                     killTimer(gameTimerId);
    150                     QMessageBox::information(this, "胜利", "恭喜你!!!");
    151                     //启动win页面
    152                     winMovie.start();
    153                     ui->stackedWidget->setCurrentWidget(ui->pageWin);
    154                     //启动定时器
    155                     winTimerId = startTimer(5000); //5s
    156                 }
    157                 //初始化字符串结果,清空
    158                 resultStr.clear();
    159             }
    160         }
    161     }
    162 }
    163 
    164 Widget::~Widget()
    165 {
    166     delete ui;
    167 }
    View Code

    4  总结

    主要有以下问题可能实现的时候会遇到:

    (1)布局

    布局这个确实不好弄,我也不太熟悉,当布局时最好先把相关联的组件放在一个Widget里面布好局之后,再进行全体布局。

    (2)按钮的字体设置在QWidget类里面,而不是在QAbstractButton里。

    (3)代码中,定时器我们是使用的定时器事件处理函数timerEvent()来做的,而不是信号与槽。

    如果代码中还有其它问题,希望网友指出来。

  • 相关阅读:
    git warning: LF will be replaced by CRLF in 解决办法
    今天买了个pro,开始ios开发
    基于pyspark的mapreduce实现
    正则表达式中全部符号作用及解释
    CNN
    tensorboard使用及tensorflow各层权重系数输出
    DeepFM tensorflow实现
    FM详解
    sklearn计算auc需要注意的点
    矩阵压缩存储(可用于FM算法中的稀疏矩阵存储)
  • 原文地址:https://www.cnblogs.com/mrlayfolk/p/13235422.html
Copyright © 2011-2022 走看看