基于QT的智慧交通管理系统(Day1)
本文用于记录学期期末实训内容,智慧交通系统设计,硬件使用Qt仿真。软件使用Qt做一个界面—界面设计、开发,信号和槽,事件,网络编程。界面会显示车辆的运行信息,并且可以远程控制车辆的状态。尽可能做到保姆级别的详细步骤
本文用于记录学期期末实训内容,尽可能做到保姆级别的详细步骤,跟着做准能成
第一次写博客,请多担待
在整个工程中任何的路径不要有任何中文字符!!!
声明:我也只是个学习一般的学生,这是记录课上老师讲的内容,我现在只能说这么做能行,但我还不清楚为什么这样做,还在努力学习中。
目录
项目要求
·硬件使用Qt仿真,软件使用Qt
·做一个界面—界面设计、开发,信号和槽,事件,网络编程
·界面会显示车辆的运行信息,并且可以远程控制车辆的状态
安装QT
我使用的是QT5.14.2,安装前先断网

不断网的话需要注册,比较麻烦,像这样子

然后安装

选择需要的组件,我选择了 全选

然后下一步,同意协议,下一步,开始安装即可,安装耗时大约10min~30min左右,耐心等待。
创建工程
文件->新建工程或项目->在项目中选择Application->QT Widgets Application
一路“下一步”到details页面,设置类名,然后基本类选QWidget,记得确定Generate form有被勾选
Kit选择Desktop Qt 5.14.2 WinGW 64-bit
点击下一步,知道完成创建
点击左下角的绿色三角,会弹出一个窗口,我们的项目就在其中实现
基本的界面布局
先放一个大致的效果,然后咱们说步骤

步骤
选择Form下的mainwindow.ui,双击跳转到ui编辑页面

长这样

Button下的PushButton往里面拖几个,我拖了7个
双击拖进去的PushButton,修改上面的名字,我分别改成了

再拖一根Stacked Widget进去,充当不同功能的页面
再从Containers里拖一个widget出来(注意,一定要放到第一层面板里,不要拖进stacked widget里面)

把PushButton们拖进widget里面,然后选中widget点击“水平布局”(框外那一排小按钮里) 
给widget里的PushButton们设置一下样式
编写方式类似CSS样式表,点击”apply“
QPushButton{
height:40px;
font: 24pt "隶书";
color:rgb(0, 0, 0);
background-color:rgb(38, 21, 100);
}
效果(随便弄的,有点丑,哈哈)

(出了一个小插曲 ,mian.cpp里面的这个默认MainWindow,报错了,改成Mainpage)

选中主面板,然后设置为水平布局

拉一个弹簧(Vertical Spacer)用来隔开”系统设置“和”退出“
接下来进一步优化按钮的效果,添加一个悬停和选中的样式改变
QPushButton{
height:40px;
font: 24pt "隶书";
color:rgb(0, 0, 0);
background-color:rgb(38, 21, 100);
}
QPushButton::hover{
color:rgb(170, 0, 0);
background-color:rgbrgb(85, 255, 0);
}
QPushButton::pressed{
color:rgb(255, 170, 255);
background-color:rgbrgbrgb(255, 255, 127);
}
效果:(红配绿,哈哈哈哈)

打开项目文件夹

将素材文件夹放入其中,以下素材是我自己找到
推荐在阿里巴巴矢量库自行下载


那么接下来把素材导入工程

选择Qt->QT Resource File
点击choose然后随便起个名,下一步,完成

进入到这个界面,然后点击Add Prefix,修改前缀,放入素材,然后CTRL+S。

添加完成后,我们返回UI给PushButton添加图标


效果是这样

最后浅浅地给标题栏添加一个图标和名称吧

放置在mainpage.cpp的Mainpage::Mainpage(QWidget *parent): QWidget(parent), ui(new Ui::Mainpage)里
//设置文本框名称
this->setWindowTitle(QStringLiteral("智慧交通系统"));
// 访问到资源
QIcon icon(":/icon/Image/mao.png");
// 设置图标
this->setWindowIcon(icon);
功能实现
退出功能
这个功能最简单,利用信号与槽机制,转到槽,编辑槽函数,this->close();
信号与槽机制
声明了信号的对象,当其状态改变时,信号由该对象发送出去,槽用于接收和处理信号。当一个信号被发射时,与其相关联的槽将被立刻执行,就像一个正常的函数调用一样。



这样就实现了退出的功能
绘制主界面
QT事件
在QT系统中,事件是一种对象。他代表用户的某种操作或操作系统的某种行为。当用户在窗体中做出某种操作时往往会产生事件。
发生在stacked widget上的事件
在mianpage.h中写一个函数声明
protected:
//事件过滤器,重写stackWidget中的绘图事件
bool eventFilter(QObject *obj,QEvent *event);
/*QObject *obj:
该参数是一个指向 QObject 类型的指针。QObject 是 Qt 框架中的基类,许多 Qt 类都继承自 QObject。obj 表示产生事件的对象,例如,在一个 GUI 应用程序中,它可以是一个按钮、标签、窗口等。当事件发生时,该参数会指向触发该事件的对象。
QEvent *event:
该参数是一个指向 QEvent 类型的指针。QEvent 是 Qt 中表示事件的基类,Qt 中存在许多派生自 QEvent 的事件类,例如 QMouseEvent(鼠标事件)、QKeyEvent(键盘事件)、QPaintEvent(绘制事件)等。event 包含了事件的详细信息,例如事件的类型、发生的位置(对于鼠标事件)、按下的键(对于键盘事件)等。*/

光标移动到eventFilter上然后Alt+enter,回车,自动把函数实现写好


返回ui修改名称,第一个page改成了page_map

点击左下角的锤子重新构建

在这里多添加一句,他的事件由我们自己来过滤
ui->page_map->installEventFilter(this);
根据帮助手册编写函数
选中event Filter右击,选择上下文,Object,查看

bool Mainpage::eventFilter(QObject *obj, QEvent *event)
{
// 检查事件源对象是否为 ui->page_map
if (obj == ui->page_map) {
// 检查事件是否为绘制事件(QEvent::Paint)
if (event->type() == QEvent::Paint) {
// 创建一个 QPainter 对象,并将 ui->page_map 作为绘图设备
QPainter painter(ui->page_map);
// 从资源路径 :/icon/Image/RoadMap.png 加载一个 QImage 对象
QImage img(":/icon/Image/RoadMap.png");
// 遍历 list_road 中的每个 Road 对象
for (auto item : list_road) {
// 使用 painter 绘制道路,起点为 item.start,终点为 item.end
painter.drawLine(item.start, item.end);
}
// 在 ui->page_map 的矩形区域内绘制图像 img
painter.drawImage(ui->page_map->rect(), img, img.rect());
// 表示此绘制事件已被处理,不会再传递给其他对象处理
return true;
} else {
// 对于其他事件类型,不进行处理,返回 false
return false;
}
} else {
// 如果事件源对象不是 ui->page_map,则将事件传递给父类的事件过滤器进行处理
return QWidget::eventFilter(obj, event);
}
}
效果图

画线
让程序在地图上画线
、首先在工程文件add new,类型为C++头文件
在当中添加代码
#ifndef COMMON_H
#define COMMON_H
#include<QPoint>
//道路的构造函数
struct Road{
public:
Road(const int &id,QPoint &start,const QPoint &end):
id(id),
start(start),end(end)
{
}
int id;
QPoint start,end;
};
#endif // COMMON_H
在mainpage.h中添加头文件

在这里添加一句 QList<Road>list_road;

初始化道路信息,Alt+enter

画道路(mainpage.cpp)
bool Mainpage::eventFilter(QObject *obj, QEvent *event)
{
if (obj == ui->page_map) {
if (event->type() == QEvent::Paint) {
// QPainter painter(ui->page_map);
QPainter painter;
QImage img(":/icon/Image/RoadMap.png");
painter.begin(&img);
//画道路
for(auto item:list_road){
painter.drawLine(item.start,item.end);
}
painter.end();
painter.begin(ui->page_map);
painter.drawImage(ui->page_map->rect(),img,img.rect());
painter.end();
return true;
} else {
return false;
}
} else {
// pass the event on to the parent class
return QWidget::eventFilter(obj, event);
}
}
void Mainpage::initRoad()
{
int id=0;
Road road1(id++,QPoint(85,34),QPoint(756,34));
list_road.append(road1);
Road road2(id++,QPoint(756,65),QPoint(85,65));
list_road.append(road2);
Road road3(id++,QPoint(31,86),QPoint(31,332));
list_road.append(road3);
Road road4(id++,QPoint(62,332),QPoint(62,86));
list_road.append(road4);
Road road5(id++,QPoint(778,86),QPoint(778,352));
list_road.append(road5);
Road road6(id++,QPoint(810,332),QPoint(810,86));
list_road.append(road6);
Road road7(id++,QPoint(756,349),QPoint(85,349));
list_road.append(road7);
Road road8(id++,QPoint(85,380),QPoint(756,380));
list_road.append(road8);
Road road9(id++,QPoint(31,404),QPoint(31,655));
list_road.append(road9);
Road road10(id++,QPoint(62,655),QPoint(62,404));
list_road.append(road10);
Road road11(id++,QPoint(778,404),QPoint(778,655));
list_road.append(road11);
Road road12(id++,QPoint(810,655),QPoint(810,404));
list_road.append(road12);
Road road13(id++,QPoint(756,675),QPoint(85,675));
list_road.append(road13);
Road road14(id++,QPoint(85,706),QPoint(756,706));
list_road.append(road14);
}
优化道路线条(在Mainpage::eventFilter中)
QPen pen;
pen.setColor(QColor(0,255,0));
pen.setWidth(3);
painter.setPen(pen);

效果:

红绿灯
在common.h里添加代码
//红绿灯
struct SingalLamp{
public:
int count;//倒计时
// int r_duration;给一个总的持续时间
QColor color;//信号灯的颜色
};
//路口
struct Cross{
public:
Road *N_exit,*N_entrance,
*S_exit,*S_entrance,
*E_exit,*E_entrance,
*W_exit,*W_entrance;
int id;
QRect local;
QList<SingalLamp *>list_sl;//保存路口的信号灯
QMap<Road *,SingalLamp *>road_sl;//可以得到道路和信号灯的关系
};
在mainpage.cpp添加
QList<Cross>list_cross;和void initCross();


void Mainpage::initCross(){
int id = 0;
Cross cross1(id++);
SignalLamp *sl1 =new SignalLamp;
SignalLamp *sl2 =new SignalLamp;
cross1.list_sl.append(sl1);
cross1.list_sl.append(sl2);//信号灯和路口联合起来
// cross1.
}
之前这里有少写东西,对照补上

该部分总代码
common.h
#ifndef COMMON_H
#define COMMON_H
#include<QPoint>
#include <qcolor.h>
#include <qmap.h>
#include <qrect.h>
// 道路的构造函数
struct Road{
public:
// 构造函数,接收三个参数:id、起点和终点
// 使用初始化列表初始化成员变量
Road(const int &id,const QPoint &start,const QPoint &end):
id(id),
start(start),
end(end)
{
// 这里可以添加更多的初始化逻辑,如果需要的话
}
// 道路的标识符
int id;
// 道路的起点
QPoint start;
// 道路的终点
QPoint end;
};
// 红绿灯
struct SignalLamp{
public:
// 倒计时
int count;
// int r_duration;给一个总的持续时间,可以根据需要添加这个成员变量
// 信号灯的颜色
QColor color;
};
// 路口
struct Cross{
public:
// 构造函数,接收一个 id 作为参数,使用初始化列表初始化成员变量
Cross(const int &id):id(id){}
// 北方向的出口和入口道路指针
Road *N_exit,*N_entrance,
// 南方向的出口和入口道路指针
*S_exit,*S_entrance,
// 东方向的出口和入口道路指针
*E_exit,*E_entrance,
// 西方向的出口和入口道路指针
*W_exit,*W_entrance;
// 路口的标识符
int id;
// 路口的矩形区域,可用于表示路口的位置和范围
QRect local;
// 保存该路口的信号灯列表,存储 SignalLamp 指针
QList<SignalLamp *>list_sl;
// 存储道路和信号灯的映射关系,方便根据道路找到对应的信号灯
QMap<Road *,SignalLamp *>road_sl;
};
#endif // COMMON_H
mainpage.h
#ifndef MAINPAGE_H
#define MAINPAGE_H
#include "common.h"
#include <QWidget>
// Qt 的命名空间宏,开始
QT_BEGIN_NAMESPACE
namespace Ui { class Mainpage; }
// Qt 的命名空间宏,结束
QT_END_NAMESPACE
// 定义 Mainpage 类,继承自 QWidget
class Mainpage : public QWidget
{
Q_OBJECT
public:
// 构造函数,可传入父部件指针,默认为 nullptr
Mainpage(QWidget *parent = nullptr);
// 析构函数
~Mainpage();
protected:
// 事件过滤器,用于处理来自 QObject 的事件,特别是重写 stackWidget 中的绘图事件
bool eventFilter(QObject *obj,QEvent *event);
private slots:
// 自定义的槽函数,通常用于处理按钮点击等信号,这里可能是退出按钮点击的槽函数
void on_psbt_exit_clicked();
private:
// 初始化道路信息的私有成员函数
void initRoad();
// 初始化路口信息的私有成员函数
void initCross();
// Qt 的 UI 类指针,用于访问 UI 界面元素
Ui::Mainpage *ui;
// 存储道路信息的容器,存储 Road 结构体对象
QList<Road> list_road;
// 存储路口信息的容器,存储 Cross 结构体对象
QList<Cross> list_cross;
};
#endif // MAINPAGE_H
mainpage.cpp
#include "mainpage.h"
#include "ui_mainpage.h"
#include <QPainter>
// Mainpage 类的构造函数
Mainpage::Mainpage(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Mainpage)
{
// 调用 setupUi 函数初始化 UI 界面
ui->setupUi(this);
// 设置窗口的标题为 "智慧交通系统"
this->setWindowTitle(QStringLiteral("智慧交通系统"));
// 从资源中加载图标
QIcon icon(":/icon/Image/mao.png");
// 设置窗口的图标
this->setWindowIcon(icon);
// 为 ui->page_map 部件安装事件过滤器,事件过滤器为当前 Mainpage 对象
ui->page_map->installEventFilter(this);
// 调用 initRoad 函数初始化道路信息
initRoad();
}
// Mainpage 类的析构函数
Mainpage::~Mainpage()
{
// 释放 ui 相关资源
delete ui;
}
// 事件过滤器函数,用于处理事件
bool Mainpage::eventFilter(QObject *obj, QEvent *event)
{
// 检查事件源对象是否为 ui->page_map
if (obj == ui->page_map) {
// 检查事件是否为绘制事件(QEvent::Paint)
if (event->type() == QEvent::Paint) {
// 创建一个 QPainter 对象,这里存在问题,未指定绘图设备
QPainter painter;
// 从资源路径加载图像
QImage img(":/icon/Image/RoadMap.png");
// 开始在 img 上进行绘制操作,这里存在问题,应在 ui->page_map 上绘制
painter.begin(&img);
// 创建 QPen 对象,用于绘制道路
QPen pen;
// 设置画笔颜色为绿色,可使用 Qt::green 常量
pen.setColor(Qt::green);
// 设置画笔宽度为 3
pen.setWidth(3);
// 将画笔设置给 painter
painter.setPen(pen);
// 遍历 list_road 列表,绘制道路
for(auto item : list_road) {
painter.drawLine(item.start, item.end);
}
// 结束在 img 上的绘制操作
painter.end();
// 开始在 ui->page_map 上进行绘制操作,这里存在问题,绘制操作混乱
painter.begin(ui->page_map);
// 将图像绘制在 ui->page_map 的矩形区域内
painter.drawImage(ui->page_map->rect(), img, img.rect());
// 结束在 ui->page_map 上的绘制操作
painter.end();
// 表示此绘制事件已被处理,不会再传递给其他对象处理
return true;
} else {
// 对于其他事件类型,不进行处理,返回 false
return false;
}
} else {
// 将事件传递给父类的事件过滤器进行处理
return QWidget::eventFilter(obj, event);
}
}
// 处理退出按钮点击的槽函数,用于关闭窗口
void Mainpage::on_psbt_exit_clicked()
{
this->close();
}
// 初始化道路信息的函数
void Mainpage::initRoad()
{
int id=0;
Road road1(id++,QPoint(85,34),QPoint(756,34));
list_road.append(road1);
Road road2(id++,QPoint(756,65),QPoint(85,65));
list_road.append(road2);
Road road3(id++,QPoint(31,86),QPoint(31,332));
list_road.append(road3);
Road road4(id++,QPoint(62,332),QPoint(62,86));
list_road.append(road4);
Road road5(id++,QPoint(778,86),QPoint(778,352));
list_road.append(road5);
Road road6(id++,QPoint(810,332),QPoint(810,86));
list_road.append(road6);
Road road7(id++,QPoint(756,349),QPoint(85,349));
list_road.append(road7);
Road road8(id++,QPoint(85,380),QPoint(756,380));
list_road.append(road8);
Road road9(id++,QPoint(31,404),QPoint(31,655));
list_road.append(road9);
Road road10(id++,QPoint(62,655),QPoint(62,404));
list_road.append(road10);
Road road11(id++,QPoint(778,404),QPoint(778,655));
list_road.append(road11);
Road road12(id++,QPoint(810,655),QPoint(810,404));
list_road.append(road12);
Road road13(id++,QPoint(756,675),QPoint(85,675));
list_road.append(road13);
Road road14(id++,QPoint(85,706),QPoint(756,706));
list_road.append(road14);
}
// 初始化路口信息的函数
void Mainpage::initCross()
{
int id = 0;
// 创建 Cross 对象 cross1
Cross cross1(id++);
// 创建两个 SignalLamp 对象,并分配内存
SignalLamp *sl1 = new SignalLamp;
SignalLamp *sl2 = new SignalLamp;
// 将 SignalLamp 对象添加到 cross1 的 list_sl 列表中
cross1.list_sl.append(sl1);
cross1.list_sl.append(sl2);
// 信号灯和路口联合起来
}
更多推荐


所有评论(0)