QT项目——猜数字小游戏

学了这么久的QT,决定使用QT写一个猜数字的小游戏来锻炼自己对QT应用。

先使用一个stackedWidget来存放两个页面,一个页面是开始页面,另一个页面是游戏页面,不得不说这个容器真的很好使用,我一开始还准备使用字父窗口来实现主界面和游戏界面的切换。

主窗口的头文件代码

#ifndef GUESSNUM_H
#define GUESSNUM_H

#include <QWidget>
#include<QString>
#include"youwin.h"
#include"youloss.h"
QT_BEGIN_NAMESPACE
namespace Ui { class GuessNum; }
QT_END_NAMESPACE

class GuessNum : public QWidget
{
    Q_OBJECT

public:
    GuessNum(QWidget *parent = nullptr);
    void timerEvent(QTimerEvent*)override;
    ~GuessNum();
public slots:
    void close_or_not();
    void openGame();
    void For_button();
private slots:
    void on_back_clicked();

private:
    Ui::GuessNum *ui;
    int GameTime;//游戏总时长
    int lastTime;//剩余游戏时长
    int Curtime;//触发计时器事件的间隔
    QString result;//最终结果的字符串
    QString The_Number_to_guess;//所需要猜的数字
    youWin win_widget;//获胜的窗口
    youLoss loss_widget;//失败的窗口
};
#endif // GUESSNUM_H

来说一下我遇到的一些问题,进度条的移动这个操作就是需要设置一个计时器,在点击按钮开始游戏的同时就开始计时,然后有一个时间事件函数,把timeId设置为每1000ms触发一次时间事件函数,然后时间事件函数所执行的操作是不断的对剩余时间进行自减操作,然后设定进度条的当前时间这样就可以实现进度条的移动了。还有一点需要十分注意,就是开始游戏这个按钮如果在鼠标点击的时候时间长了一点,有可能会触发两次会产生BUG,所以我们在开始游戏的按钮的槽函数中对按钮进行blockSignals(true)函数的操作来切断按钮对点击产生的信号,然后在返回主页面的时候再连接上。而我对游戏界面中的0~9所有按钮都执行的是同一个槽函数,在槽函数中使用sender()函数来获取所点击的按钮,再对返回值进行类型转换,然后获取按钮中的内容,把内容加到结果字符串上,当内容字符串到达4位的时候进行正确与否的判断,错误就清空结果字符串,正确就播放可爱的桥本环奈的动图界面并跳回主界面初始化所有数据,而且停止计时器的触发。而游戏失败是在时间事件函数中进行判断的,由于一旦猜中就会停止计时器的触发,如果计时器剩余时间等于0的时候就会直接宣布游戏失败并跳转到失败页面,同时初始化所有数据,过一会就会跳转到游戏主界面从新开始。还有对于下拉框时间的选择问题上,comboBox有一个函数可以获取选择的字符串再把字符串转换为整型数,但是我的字符串中有字母,所以不能直接转换。因此我选择使用获取下标的方法来转换获得总的游戏时间。

主窗口的实现文件代码:

#include "guessnum.h"
#include "ui_guessnum.h"
#include<QDebug>
#include<QLabel>
#include<QPushButton>
#include<QMessageBox>
#include<QTimer>
#include<QTime>
GuessNum::GuessNum(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::GuessNum)
{
    ui->setupUi(this);
    this->setWindowTitle("猜数字");
    resize(800,400);
    ui->stackedWidget->setCurrentIndex(0);
    Curtime=0;
    //关联上“退出游戏”按钮
    connect(ui->close,&QPushButton::released,this,&GuessNum::close_or_not);
    //关联上“开始游戏“按钮
    connect(ui->start,&QPushButton::pressed,this,&GuessNum::openGame);
    //关联上数字键盘按钮
    connect(ui->play0,&QPushButton::pressed,this,&GuessNum::For_button);
    connect(ui->play1,&QPushButton::pressed,this,&GuessNum::For_button);
    connect(ui->play2,&QPushButton::pressed,this,&GuessNum::For_button);
    connect(ui->play3,&QPushButton::pressed,this,&GuessNum::For_button);
    connect(ui->play4,&QPushButton::pressed,this,&GuessNum::For_button);
    connect(ui->play5,&QPushButton::pressed,this,&GuessNum::For_button);
    connect(ui->play6,&QPushButton::pressed,this,&GuessNum::For_button);
    connect(ui->play7,&QPushButton::pressed,this,&GuessNum::For_button);
    connect(ui->play8,&QPushButton::pressed,this,&GuessNum::For_button);
    connect(ui->play9,&QPushButton::pressed,this,&GuessNum::For_button);

}

GuessNum::~GuessNum()
{
    delete ui;
}
void GuessNum::close_or_not()
{
    int res=QMessageBox::question(this,"问题","是否退出结束游戏?");
    if(res==QMessageBox::Yes)
    {
        this->close();
    }
}
void GuessNum::openGame()
{
    ui->stackedWidget->setCurrentIndex(1);

    ui->start->blockSignals(true);//切断信号传递,预防多次点击

    int num;
    //生成随机的目标四位数
    //以从0时0分0秒到现在的秒数为种子
    qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
    //调用全局的qrand()函数生成随机数,对10000取余,保证位于10000以内
    while((num=qrand()%10000)<999);//这里的循环为了确保数字是一个四位数
    The_Number_to_guess=QString::number(num);//把所获得的随机数转换为字符串

    qDebug()<<The_Number_to_guess;

    //获取下拉框的时间
    int index=ui->comboBox->currentIndex();
    GameTime=60+index*10;
    lastTime=GameTime;
    //给进度条设定时间
    ui->progressBar->setMinimum(0);
    ui->progressBar->setMaximum(GameTime);
    ui->progressBar->setValue(GameTime);

    //qDebug()<<Curtime;

    //计时器开始
    Curtime=this->startTimer(1000);

}
void GuessNum::timerEvent(QTimerEvent *)
{
    if(lastTime==0)//当时间用尽的时候,说明挑战失败
    {
        this->killTimer(Curtime);
        ui->textBrowser->append("游戏失败!!");
        QMessageBox::about(this,"失败","很遗憾你没有在规定时间内猜出正确数字!!");
        ui->textBrowser->clear();
        result.clear();
        The_Number_to_guess.clear();
        ui->start->blockSignals(false);

        //播放失败页面
        loss_widget.show();
        //跳转页面
        ui->stackedWidget->setCurrentIndex(0);
    }
    else
    {
        lastTime--;
        ui->progressBar->setValue(lastTime);
    }
}
void GuessNum::For_button()
{
    QObject*mySender=this->sender();//获取所点击的按钮
    QPushButton*Button_Pointer=(QPushButton*)mySender;
    if(Button_Pointer!=nullptr)
    {
        QString Button_Text=Button_Pointer->text();//获取按钮中的内容
        result+=Button_Text;
        if(result.size()==1&&result=="0")
        {
            result.clear();
        }
        ui->textBrowser->setText(result);
        if(result.size()==4)//当位数满足的时候
        {
            if(result>The_Number_to_guess)//所猜结果大了一点
            {
                ui->textBrowser->append("数字大了点");
                result.clear();
            }
            else if(result<The_Number_to_guess)//所猜结果小了一点
            {
                ui->textBrowser->append("数字小了点");
                result.clear();
            }
            else//猜中结果
            {
                ui->textBrowser->append("恭喜你猜对了");
                this->killTimer(Curtime);//计时器停止
                QMessageBox::about(this,"成功","恭喜你猜对了!!");
                ui->textBrowser->clear();
                result.clear();
                The_Number_to_guess.clear();
                ui->start->blockSignals(false);

                //插入播放胜利动画的页面
                win_widget.show();
                //跳转页面
                ui->stackedWidget->setCurrentIndex(0);
            }
        }
   }
}

//回退按钮
void GuessNum::on_back_clicked()
{
    if(result.size()==1)
    {
        result.clear();
        ui->textBrowser->clear();
    }
    else if(result.size()==0)
    {
        ui->textBrowser->setText("请输入数字噢!!");
    }
    else
    {
        result.chop(1);//截断最后一位字符
        //result[result.size()-1]='\0';这样也可以
        ui->textBrowser->setText(result);
    }
}

我这两个窗口是使用子父窗口来实现的,因为我不知道怎么在stackedWidget中添加新的页面……但是还是有需要注意的地方,一开始我使用QPainter和QPixmap来实现整个窗口的背景图,发现实现不了,然后使用了一个和窗口一样大的标签来贴QMovie,从而实现了这个需求而对于定时关闭窗口这个需求,我一开始没想到close函数,后来使用计时器和close函数来实现定时关闭窗口最后记得关闭计时器噢!!

胜利窗口头文件代码:

#ifndef YOUWIN_H
#define YOUWIN_H

#include <QWidget>
#include<QLabel>
#include<QTimerEvent>
class youWin : public QWidget
{
    Q_OBJECT
public:
    explicit youWin(QWidget *parent = nullptr);
    void timerEvent(QTimerEvent*);
signals:
private:
   int timeId;
};

#endif // YOUWIN_H

胜利窗口实现代码:

#include "youwin.h"
#include<QLabel>
#include<QMovie>
#include<QTimer>
youWin::youWin(QWidget *parent) : QWidget(parent)
{
    this->resize(800,550);
    this->setWindowTitle("你赢了噢!!!");
    timeId=0;
    timeId=this->startTimer(5000);
    QLabel*p=new QLabel(this);
    p->resize(this->width(),this->height());
    p->show();
    QMovie*mov=new QMovie(":/new/prefix1/C:/Users/13764/Desktop/PARTS/QT/victory.gif");
    p->setMovie(mov);
    mov->start();
    p->setScaledContents(true);
}
void youWin::timerEvent(QTimerEvent *)
{
    this->killTimer(timeId);
    this->close();
}

失败窗口头文件代码:

#ifndef YOULOSS_H
#define YOULOSS_H

#include <QWidget>

class youLoss : public QWidget
{
    Q_OBJECT
public:
    explicit youLoss(QWidget *parent = nullptr);
    void timerEvent(QTimerEvent*);
signals:
private:
    int timeId;
};

#endif // YOULOSS_H

失败窗口实现文件代码:

#include "youloss.h"
#include<QLabel>
#include<QMovie>
#include<QTimer>
youLoss::youLoss(QWidget *parent) : QWidget(parent)
{
    this->resize(800,550);
    this->setWindowTitle("你输了噢!!!");
    timeId=0;
    timeId=this->startTimer(5000);
    QLabel*p=new QLabel(this);
    p->resize(this->width(),this->height());
    p->show();
    QMovie*mov=new QMovie(":/new/prefix1/C:/Users/13764/Desktop/PARTS/QT/default.gif");
    p->setMovie(mov);
    mov->start();
    p->setScaledContents(true);
}
void youLoss::timerEvent(QTimerEvent *)
{
    this->killTimer(timeId);
    this->close();
}

运行:

主窗口的主界面

主窗口的游戏界面 

 

当游戏胜利时

 

 

当游戏失败时 

 

 

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
天气预报是一个非常实用的个人项目,它可以帮助我们及时了解当地的天气情况,帮助我们合理安排日常生活和外出计划。 我的qt个人项目天气预报主要包括以下功能: 1. 实时天气查询:通过调用天气API,可以实时获取当地的天气信息,包括温度、湿度、风力、空气质量等指标。用户可以根据自己的需求选择查询当天或未来几天的天气情况。 2. 城市选择和管理:用户可以通过界面上的搜索功能输入城市名字查询该城市的天气情况。同时,用户还可以通过添加和删除城市的功能,方便地管理自己关注的城市列表。 3. 天气图标和背景:界面上会显示对应的天气图标,如晴天、多云、雨天等,以直观地展示当前的天气情况。同时,根据不同的天气状况,背景图片也会相应地进行变化,增加界面的美观性和可视化效果。 4. 未来天气预测:除了显示当天的天气情况外,我的个人项目还可以提供未来几天的天气预测,帮助用户更全面地了解未来几天的天气变化趋势。 通过这个个人项目,用户可以方便地获取并查看天气信息,从而更好地做出日常生活安排。此外,用户还可以根据天气预报的变化,做出适应性的衣物搭配和外出计划,提高生活效率和便利性。 总之,我的qt个人项目天气预报能够为用户提供准确、及时的天气信息,并通过直观的界面展示,帮助用户做出合理的日常生活安排和外出计划。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值