校园导航系统CampusNavigation(C++实现)
课程设计选题及要求
选题 6:校园导航系统
设计一个校园导航系统,为学校来访者提供各种信息查询服务,方便查找学校主要单位、校园景点之间最短距离,并能及时对该图进行更新,地点信息包括名称、代号、相关介绍等,及两个地点之间有直接路径的距离
基本功能与技术要求
- 数据文件管理功能:创建新文件、打开文件、保存文件。
- 计算与统计功能,完成记录中相关数据的统计;
- 能够打开已存在的数据表文件,计算任意两个地点之间的最短路径的长度及途经地点。
- 提供来访者从出发地到目的地的路线统计,以图示界面输出。
- 记录管理功能:记录的管理采用链表、数组等实现。
- 输入/添加/插入记录,并保存到数据文件中。
- 查询、显示记录,根据用户要求按所给地点查询单位或景点信息,以及到地点的问路情况等。
- 修改记录:能够打开已存在的数据表文件,并对确定的任意记录进行修改,在修改过程中,应显示记录信息,给出确认提示,并对更新的记录信息进行文件保存。
- 删除记录:能够打开已存在的数据表文件,可以删除数据表中的任一记录,要求具备逻辑删除(具有恢复功能)和物理删除功能,并对新的数据表信息进行文件保存。
设计思路
整体模式以及主要涉及的模块 整体设计采用 MVC 模式,及数据的储存处理与表现分离。使用 QT 框架提供基础的图形界面操作,整体分为三个模块,
CNView
前端部分负责数据的显示,CNModel
数据的储存预处理。- 模块功能的划分以及类的初步设计
CNView
前端部分 主要结合 QT 框架,界面展示,地点展示,路径展示,以及提供对应的 GUI 工具实现文本的录入CNModel
后端部分
功能设计和模块划分
本次课程设计额
C++父类指针操作子类新函数的方式
父类指针无法直接调用子类的新函数,需要转换为子类的指针后方可调用。
C++编译器在编译的时候是做静态类型分析。也就是说,你的父类指针是否真的指向一个子类类型,编译器并不会做这个假设。所以你用父类指针去调用子类的函数是无法被识别的。这里提供一种不安全和一种安全的转换方式可以实现该功能: 假设我们有父类和子类的定义如下:
1 |
|
- 强制转换(不安全)
1 |
|
这里之所以说不安全是因为转换的时候无法得知是否转换成功。编译器强制把 d 当成 Derived 类型去使用。比如说 b 本来是真的指向 Base 而不是 Derived 类型那么强制转换后调用 Derived 的 NewFunc 可能会导致程序崩溃。
2.动态转换,dynamic_cast(安全)
1 |
|
dynamic_cast 是在运行时去做转换而非编译时,所以它可以给出是否转换成功的信息。如果转换不成功则返回 NULL。所以可以判断转换结果是否为 NULL 来决定是否能使用该指针不会导致程序崩溃
第一天进度记录
- 完成后端 1/2(除去文件读写)
- string index 放着先不实现,所有都先按照鼠标事件和 xy 坐标来写
- 明早补充边的增加和删减 注意边增添的时候算直线距离
- 普通点的增加和删减
第 X 天进度记录
就是说如果槽的命名是这样的话:
1 |
|
就会自动将widget name
中的信号signal name
和这个槽void on_<widget name>_<signal name>(<signal parameters>)
链接起来。
这是 QT 不需要 connect 语句就可以自动链接信号和槽的机制!
绘图相关
当发生一下情况时会产生绘制事件并调用 paintEvent()函数:
在窗口部件第一次显示时,系统会自动产生一个绘图事件,从而强制绘制这个窗口部件。
当重新调整窗口部件的大小时,系统也会产生一个绘制事件。
当窗口部件被其他窗口部件遮挡,然后又再次显示出来的时候,就会对那些隐藏的区域产生一个绘制事件。
同时可以调用 QWidget::update()或者 QWidget::repaint()来强制产生一个绘制事件。二者的区别是:
repaint()函数会强制产生一个即时的重绘事件,而 update()函数只是在 Qt 下一次处理事件时才调用一次绘制事件。
如果多次调用 update(),Qt 会把连续多次的绘制事件压缩成一个单一的绘制事件,这样可避免闪烁现象。
使用 repaint()
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!