《数据结构、算法与应用 —— C++语言描述》学习笔记 — 栈 —— 应用 —— 迷宫老鼠

一、问题描述

迷宫是一个矩形区域,有一个入口和一个出口。迷宫内部包含不能穿越的墙壁或障碍物。这些障碍物沿着行和列防止,与迷宫的边界平行。迷宫的如果在左上角,出口在右下角。
在这里插入图片描述
我们可以使用一个 bool 矩阵来描述这个迷宫。当矩阵中某个位置有障碍时,其值为 ture,否则为 false。迷宫老鼠问题是要寻找一条从入口到出口的路径。路径是一个由位置组成的序列。每一个位置都没有障碍,而且除入口之外,路径上的每个位置是前一个位置在东、南、西、北上相邻的一个位置。

二、设计

我们采用自顶向下的方法设计这个程序。不难理解,这个程序有三个部分:输入迷宫,寻找路径和输出路径。书中使用三个模块实现这些部分。我们这里把输入和输出模块作为放在一起,除此之外,我们还有一个模块用于显示欢迎信息、软件名称及作者信息。为了简便,我们这里使用QT6.1.2 开发。

1、思路

该程序主体流程是:进入欢迎界面;让用户设置迷宫形状;根据用户的需要绘制迷宫;在用户点击寻找路径的按钮时绘制路径(支持多次绘制,暂不支持擦除)。
首先思考主体界面。主体界面自身有一个类。其实例中应该还有含有两个子对象。分别用于存放欢迎界面和迷宫界面(可以将设置界面独立)。由于这两个子对象不会同时显示,我们可以考虑使用 QStackedWidget 存放。
然后考虑欢迎界面。我们需要确认采取显示欢迎字样。这里我选择一个较为简单的淡入淡出的 label。由于该类可以由其它类复用,因此我们将公共接口提取并放在 util 文件夹中。
最后考虑迷宫界面。主体的布局采取左边为交互界面,右边为显式界面。比例为1:3。考虑到计算迷宫的策略可以动态切换,因此我们将计算迷宫的方式单独出来放在 business 文件夹中。二者之间的数据传递是一个 QVector<QVector> 用于表示地图每个矩形的状态。

2、类图

在这里插入图片描述

3、目录结构

[RatInMaze]
	RatInMaze.pro
	[document]
	[output]
	[src]
		main.cpp
		[business]
			CLS_FindPathStack.h
			CLS_FindPathStack.cpp
		[ui]
			CLS_MainWidget.h
			CLS_MainWidget.cpp
			CLS_MainWidget.ui
			CLS_Maze.h
			CLS_Maze.cpp
			CLS_Maze.ui
			CLS_Welcome.h
			CLS_Welcome.cpp
			CLS_Welcome.ui
			[util]
				CLS_LabelGradualChange.h
				CLS_LabelGradualChange.cpp

三、实现

1、ui文件

CLS_MainWidget.ui
在这里插入图片描述
CLS_Welcome.ui
在这里插入图片描述
CLS_Maze.ui
在这里插入图片描述

2、淡入淡出 label

qt 中的 css 不支持设置动画,因此需要使用定时器或线程实现淡入淡出。我们这里选择使用线程计时。淡入淡出的基本原理就是不断地改变透明度。
类声明为:

#ifndef CLS_LABELGRADUALCHANGE_H
#define CLS_LABELGRADUALCHANGE_H

#include <QLabel>

class CLS_LabelGradualChange : public QLabel
{
   
    Q_OBJECT

public:
    explicit CLS_LabelGradualChange(QWidget *parent = nullptr);
    ~CLS_LabelGradualChange();

    /*
     * @brief 设置渐变颜色
     * @param color 目标颜色
     */
    void setColor(QColor color);

    /*
     * @brief 设置淡入淡出时长
     * @param timeout 总时长
     */
    void setTimeout(int timeout);

    /*
     * @brief 设置颜色变化的总次数
     * @param timeout 总时长
     */
    void setTotalTimes(int totalTimes);

signals:
    void sigLoadFinished();

protected:
    virtual void showEvent(QShowEvent *event) override;

private:
    QString m_qstrStyleSheet;   // 预设的样式表,需要使用.arg拼接透明度
    int m_iTimeout = 0;         // 淡入淡出时长
    int m_iTotalTimes = 0;      // 颜色变化的总次数
    int m_iTimes = 0;
    bool m_blShow = true;

    void startShowThread();     // 线程中计时

private slots:
    /*
     * @brief 更新透明度槽
     */
    void slotShow();

};

#endif // CLS_LABELGRADUALCHANGE_H

实现文件:

#include "CLS_LabelGradualChange.h"
#include <QColor>
#include <QThread>

const int CONST_SHOW_TIMES = 20; // 默认显示20次

CLS_LabelGradualChange::CLS_LabelGradualChange(QWidget *parent) :
    QLabel(parent)
{
   
    m_iTotalTimes = CONST_SHOW_TIMES;
}

CLS_LabelGradualChange::~CLS_LabelGradualChange()
{
   

}

void CLS_LabelGradualChange::setColor(QColor color)
{
   
    m_qstrStyleSheet = styleSheet() + QString("color:rgba(%2,%3,%4,%5);").arg(color.red())
            .arg(color.green()).arg(color.blue());
}

void CLS_LabelGradualChange::setTimeout(int timeout)
{
   
    m_iTimeout = timeout;
}

void CLS_LabelGradualChange::setTotalTimes(int totalTimes)
{
   
    if (totalTimes > 0)
    {
   
        m_iTotalTimes = totalTimes;
    }
}

void CLS_LabelGradualChange::showEvent(QShowEvent*)
{
   
    if (m_blShow)
    {
   
        startShowThread();
        m_blShow = false;
    }
}

void CLS_LabelGradualChange::startShowThread()
{
   
    double dbInterval = double(m_iTimeout) / m_iTotalTimes;
    QThread *pThread = QThread::create([dbInterval](){
   QThread::msleep(dbInterval);});
    connect(pThread, SIGNAL(finished()), this, SLOT(slotShow()));
    pThread->start();
}

void CLS_LabelGradualChange::slotShow()
{
   
    ++m_iTimes;
    double opacity = 2.0 * double(m_iTimes >= m_iTotalTimes / 2 ? m_iTotalTimes - m_iTimes : m_iTimes) / m_iTotalTimes;
    setStyleSheet(m_qstrStyleSheet.arg(opacity));

    if (m_iTimes < m_iTotalTimes)
    {
   
        startShowThread();
    }
    else
    {
   
        emit sigLoadFinished();
    }
}

3、欢迎界面

类声明:

#ifndef CLS_WELCOME_H
#define CLS_WELCOME_H

#include <QWidget>

namespace Ui {
   
class CLS_Welcome;
}

class CLS_Welcome : public QWidget
{
   
    Q_OBJECT

public:
    explicit CLS_Welcome(QWidget *parent = nullptr);
    ~CLS_Welcome()</
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值