#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QString>
#include <QPainter>
#include<QTime>
#include<QDebug>
#include<QMouseEvent>
// 使程序休眠指定的时间(毫秒)
void sleep(unsigned int msec)
{
// 计算目标时间
QTime dieTime = QTime::currentTime().addMSecs(msec);
// 在目标时间之前,循环处理事件
while (QTime::currentTime() < dieTime)
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);//第一个参数是事件类型(这里使用 AllEvents 表示处理所有类型的事件),第二个参数是最大处理时间(这里是 100 毫秒)。
}
void MainWindow::mousePressEvent(QMouseEvent *ev)
{
if (ev->button() == Qt::LeftButton)//rightbutton右键,middlebutton滚轮键
{
QString str = QString("鼠标按下了 x = %1 y = %2 globalx = %3 globaly = %4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug() << str;
}
}
// MainWindow 类的构造函数
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
// 初始化界面
ui->setupUi(this);
this->shortes = new wangziyi;
// 初始化颜色数组
for(int i=0; i<25; i++)
{
for(int j=0; j<25; j++)
{
colors[i][j] = "lightGray";
}
}
// 将按钮映射到数组 mpb 中
mpb[0] = ui->btn_xibeimen;
mpb[1] = ui->btn_tiyuguan;
mpb[2] = ui->btn_tiyuchang;
mpb[3] = ui->btn_beimen;
mpb[4] = ui->btn_xihuan;
mpb[5] = ui->btn_donghuan;
mpb[6] = ui->btn_xilang;
mpb[7] = ui->btn_donglang;
mpb[8] = ui->btn_nantang;
mpb[9] = ui->btn_xiaohuangshan;
mpb[10] = ui->btn_xintu;
mpb[11] = ui->btn_tangdaowan;
mpb[12] = ui->btn_yanjiusheng;
mpb[13] = ui->btn_gongkee;
mpb[14] = ui->btn_wenlilou;
mpb[15] = ui->btn_nanjiao;
mpb[16] = ui->btn_jiutu;
mpb[17] = ui->btn_yifutang;
mpb[18] = ui->btn_gongkelou;
mpb[19] = ui->btn_zonghelou;
mpb[20] = ui->btn_yulanyuan;
mpb[21] = ui->btn_xiaoyiyuan;
}
// 初始化函数
void MainWindow::init()
{
// 绘制图形
for(auto x : this->shortes->List)
{
int nw = x.first, nx = x.second.first, dis = x.second.second;
QPen pen;
QPainter painter(this);
pen.setWidth(5);
pen.setColor(colors[nw][nx]);
painter.setRenderHint(QPainter::HighQualityAntialiasing, true); // 反走样
painter.setPen(pen);
painter.drawLine(QPointF(mpb[nw]->x() + 7, mpb[nw]->y() + 7), QPointF(mpb[nx]->x() + 7, mpb[nx]->y() + 7)); // 绘制直线
pen.setColor("Purple");
painter.setPen(pen);
painter.drawText(QPointF((mpb[nw]->x() + mpb[nx]->x()) / 2, (mpb[nw]->y() + mpb[nx]->y()) / 2), QString::number(dis));
}
}
// 重写绘图事件
void MainWindow::paintEvent(QPaintEvent *)
{
QPainter pbk(this);
pbk.drawPixmap(30,10,881,701,QPixmap(":/graph3.png"));
init();
}
// MainWindow 类的析构函数
MainWindow::~MainWindow()
{
delete ui;
}
// Floyd 算法打印路径
void MainWindow::floyd_print(int pre[25][25], int i, int j)
{
if(i == j) return;
if(pre[i][j] == 0)
{
colors[i][j] = colors[j][i] = "Blue";
}
else
{
floyd_print(pre, i, pre[i][j]);
floyd_print(pre, pre[i][j], j);
}
}
// Floyd 算法按钮点击事件
void MainWindow::on_btn_floyd_clicked()
{
// 检查是否选择了起点和终点
if (this->shortes->starcity == "" || this->shortes->overcity == "")
return;
// 设置当前算法为 Floyd,改变按钮样式
this->c = 1;
this->ui->btn_floyd->setStyleSheet("background-color: rgb(189, 240, 255);");//设置按钮背景为浅蓝色
this->ui->btn_dijkstra->setStyleSheet("color: rgb(0, 0, 0);");//设置按钮为无色
// 重置颜色数组,清除之前的路径标记
for (int i = 0; i < 25; i++)
{
for (int j = 0; j < 25; j++)
{
colors[i][j] = "lightGray";
}
}
update();
// 初始化距离矩阵和路径矩阵
int dis[25][25], pre[25][25];
memset(pre, 0, sizeof(pre));//将pre数组全部都初始化为0
// 将图的路径信息赋值给距离矩阵
for (int i = 0; i <= 21; i++)
{
for (int j = 0; j <= 21; j++)
{
dis[i][j] = this->shortes->G.arcs[i][j].path;
}
}
// 使用 Floyd 算法计算最短路径和路径矩阵
for (int k = 0; k <= 21; k++)
{
for (int i = 0; i <= 21; i++)
{
for (int j = 0; j <= 21; j++)
{
if (dis[i][j] > dis[i][k] + dis[k][j])
{
dis[i][j] = dis[i][k] + dis[k][j];
pre[i][j] = k;
}
}
}
}
// 标记最短路径
floyd_print(pre, this->shortes->st, this->shortes->ed);
// 在界面上显示最短距离
this->ui->label_display->setText("最短距离是:" + QString::number(dis[this->shortes->st][this->shortes->ed]));
QTextToSpeech *s =new QTextToSpeech();
s->say("最短距离是:" + QString::number(dis[this->shortes->st][this->shortes->ed]));
}
// Dijkstra 算法按钮点击事件
void MainWindow::on_btn_dijkstra_clicked()
{
// 检查是否选择了起点和终点,如果没有则直接返回
if (this->shortes->starcity == "" || this->shortes->overcity == "") return;
// 将当前算法设置为Dijkstra,改变按钮样式
this->c = 0;
this->ui->btn_dijkstra->setStyleSheet("background-color: rgb(189, 240, 255);");
this->ui->btn_floyd->setStyleSheet("color: rgb(0, 0, 0);");
// 重置颜色数组,清空之前的路径显示
for (int i = 0; i < 25; i++)
{
for (int j = 0; j < 25; j++)
{
colors[i][j] = "lightGray";
}
}
update();
int dis[25], n = 22, pre[25];
bool st[25];
// 初始化数组,其中dis表示当前节点到起点的最短距离,pre表示前驱节点,st表示是否已经加入最短路径集合
memset(st, false, sizeof(st));
memset(dis, 0x3f, sizeof(dis)); // 用较大的值表示正无穷
memset(pre, 0x3f, sizeof(pre));
dis[this->shortes->st] = 0; // 起点到自身距离为0
for (int i = 0; i < n; i++)
{
// 选择未加入最短路径集合中距离最短的节点
int t = -1;
for (int j = 0; j < n; j++)
{
if (!st[j] && (t == -1 || dis[t] > dis[j]))
t = j;
}
// 将选定节点加入最短路径集合,并更新与该节点相邻的节点的距离
st[t] = true;
if (pre[t] != 0x3f3f3f3f) colors[t][pre[t]] = colors[pre[t]][t] = "lightBlue";
update();
sleep(200);
// 循环遍历图中的每条边
for (auto x : this->shortes->List)
{
int nw = x.first, j = x.second.first, tt = x.second.second;
// 交换 j 和 nw 的值,确保 j 表示当前边的终点,nw 表示起点
if (j == t)
{
j ^= nw;
nw ^= j;
j ^= nw;
}
// 如果 nw(起点)是当前选定的节点 t
if (nw == t)
{
// 更新距离,如果找到更短的路径
if (dis[j] >= dis[t] + tt)
{
dis[j] = dis[t] + tt;
pre[j] = t;
}
}
}
// 如果已经找到目标节点,提前结束
if (t == this->shortes->ed)
break;
}
// 根据最短路径的前驱节点数组pre,标记最短路径为蓝色
中国石油大学(华东)校园导航系统
需积分: 0 63 浏览量
2024-01-22
21:29:43
上传
评论
收藏 1.47MB ZIP 举报
约束112
- 粉丝: 643
- 资源: 3
最新资源
- 基于STM32F103单片机(寄存器版)+OV7725摄像头模块照相机实验实验例程源码.zip
- 基于Python实现的桥梁易损性分析源码+代码注释.zip
- 基于python开发使用深度学习去预测股票后续的价格+源码+文档(毕业设计&课程设计&项目开发)
- flowable-designer-5.22.0.zip
- threadmanager.cpp
- 腾讯云小程序 - 一站式开发与部署平台
- 基于JSP+Java+Servlet采用MVC模式开发的购物网站+源码(毕业设计&课程设计&项目开发)
- fastgestures安装包,模拟mac的触控板收拾,两指代表右击, 三指拖拽
- 基于组态王的升降式横移立体车库控制系统+源码(毕业设计&课程设计&项目开发)
- 基于python+Django和协同过滤算法的电影推荐系统+源码(毕业设计&课程设计&项目开发)
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈