基于qt的校园导航系统的设计与实现Word文件下载.docx
《基于qt的校园导航系统的设计与实现Word文件下载.docx》由会员分享,可在线阅读,更多相关《基于qt的校园导航系统的设计与实现Word文件下载.docx(48页珍藏版)》请在冰豆网上搜索。
Second,itcanhelpvisitorsfrommanychoosetheshortestroute,atthesametimewillprovideallthepathbetweentwopoints;
Third,itcanaddsomedescriptioninlandmarkinformationandpictures,youcanalsoviewfromthebuildingtoalltheotherpathinformationofthebuilding.
Keywordspathplanning;
antalgorithm;
thecampusnavigation;
qt
1绪论
1.1概述
现在科技越来越发达,手机上的软件,电脑上的软件越来越多,所以开发小的程序也越来越有必要。
QT具备跨平台,易扩展,界面华丽,性能稳定等优点。
因此,以嵌入式处理器作为硬件平台,以QT作为程序框架,两者的完美结合必将成为未来技术的发展方向。
1.2研究背景
现在,汽车正在普及,道路不断建设,城际间的经济往来更加频繁,活动的区域也越来越大。
为了提高生活质量,大量的休闲活动、探险活动的举行使我们并不局限在自己认识的一小块区域中,不认识道路,找不到目的地的情况也屡有发生。
就此,各种各样的导航仪逐渐走进我们的生活。
无论什么导航仪最主要的部分都是电子地图。
开发电子地图成为了导航仪的关键。
根据调查,电子地图制作困难而且价格相当昂贵,给导航仪的开发带来了很多不便。
自主绘制电子地图,编写电子地图应用程序,不管是从经济上还是研究上都具有非常大的意义。
现在,各个学校都有了自己的导航系统,但是开发工具语言,还有平台不一样。
所以,如果拥有一个跨平台的程序的话,那将会给我们的开发节省了大量的时间。
QT正是一个支持多平台的C++图形用户界面应用程序框架。
它提供给应用程序开发者建立艺术级的图形用户界面所需的所用功能。
Qt是完全面向对象的很容易扩展,并且允许真正地组件编程。
所以使用QT作为应用程序框架是一个不错的选择。
1.3研究目标
本课题名为校园地理信息系统。
本系统以太原理工大学为模型,旨在建立一个本学校的导航系统,可以根据不同人的要求,足不出户,就可以浏览校园,得到各种信息
基于上述背景,开发一个校园导航项目,使用linux搭配qt来构建这个项目。
利用QT4作为系统应用层的程序框架。
开发一个可以运行的小客户端。
这个客户端虽然是在linux下开发的,但是它是可移植的,在windows下也可以运行。
1.4本章小结
本章主要介绍本项目的选题背景、意义,选题目标。
通过介绍,了解当今社会主要是校园,导航系统的需求以及重要性,明白研究该系统的必要性。
2QT简介
2.1QT的背景介绍
Qt是一个1991年由奇趣科技开发的跨平台C++图形用户界面应用程序开发框架。
它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器。
Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器(MetaObjectCompiler,moc))以及一些宏,易于扩展,允许组件编程。
2008年,奇趣科技被诺基亚公司收购,QT也因此成为诺基亚旗下的编程语言工具。
2012年,Qt被Digia收购。
2014年4月,跨平台集成开发环境QtCreator3.1.0正式发布,实现了对于iOS的完全支持,新增WinRT、Beautifier等插件,废弃了无Python接口的GDB调试支持,集成了基于Clang的C/C++代码模块,并对Android支持做出了调整,至此实现了全面支持iOS、Android、WP。
QtCreator包含了一套用于创建和测试基于Qt应用程序的高效工具,包括:
一个高级的C++代码编辑器上下文感知帮助系统可视化调试器源代码管理项目和构建管理工具.
优良的跨平台特性:
Qt支持下列操作系统:
MicrosoftWindows95/98,MicrosoftWindowsNT,Linux,Solaris,SunOS,HP-UX,DigitalUNIX(OSF/1,Tru64),Irix,FreeBSD,BSD/OS,SCO,AIX,OS390,QNX等等。
面向对象:
Qt的良好封装机制使得Qt的模块化程度非常高,可重用性较好,对于用户开发来说是非常方便的。
Qt提供了一种称为signals/slots的安全类型来替代callback,这使得各个元件之间的协同工作变得十分简单。
2.2QT实现的结构原理
Qt/Embedded是Trolltech公司开发的面向嵌入式系统的Qt版本,与X11版本的Qt在最大程度上接口兼容,采用帧缓存(framebuffer)作为底层图形接口。
Qt/Embedded类库完全采用C++封装,并且有着丰富的控件资源以及较好的可移植性,大范围的Qt/EmbeddedAPI可用于多种开发项目。
Qt/Embedded的实现结构如图2-1所示:
图2-1QT的实现结构图
Qt/Embedded的底层图形引擎基于framebuffer。
Framebuffer驱动程序的实现分为两个方面:
一方面是对LCD及其相关部分的初始化,包括画在缓冲区的创建和对DMA通道的设置;
另外一方面是对画面缓冲区的读写,具体到代码为read、write、lseek等系统调用接口。
至于将画面缓冲区的内容输出到LCD显示屏上,则由硬件自动完成。
对于软件来说是透明的。
当对于DMA通道和画面缓冲区设置完成后,DMA开始正常工作,并将缓冲区中的内容不断发送到LCD上。
这个过程是基于DMA对于LCD的不断刷新的。
基于该特性,framebuffer驱动程序必须将画面缓冲区的存储空间(物理空间)重新映射到一个不加高缓存和写缓存的虚拟地址区间中,这样能才保证应用程序通过mmap将该缓存映射到用户空间后,对于该画面缓存的写操作能够实时的体现在LCD上。
QT程序是基于C++编写的,图形用户界面编程同时需要运行效率和高水平的灵活性。
Qt通过结合C++的速度为这一领域提供了Qt对象模型。
Qt把下面这些特性添加到了C++当中:
一种被称为信号和槽的非常强大的机制;
可查询和可设计的属性项;
强大的事件和事件过滤器;
根据上下文进行国际化的字符串翻译;
完善的时间间隔驱动的计时器等。
许多Qt的特性是基于QObject的继承,通过标准C++技术实现的。
QApplication是必须构造的Qt主对象,需要在一开始的时候就构造这个对象,并把命令行参数传递给这个对象,每个Qt应用程序有且仅有一个QApplication对象,该对象必须在做其他事之前创建,这个对象处理一些底层操作,如事件处理、字符串本地化和控制界面外观等。
信号和信号处理函数是GUI应用程序用来响应用户输入的基本机制,也是所有GUI库的核心特征,Qt的信号处理机制由信号(signal)和槽(slot)构成,它们相当于GTK+中的信号和回调函数。
在Qt中回调函数就叫做槽。
信号和槽用于对象间的通讯,它的基本语法为:
connect(object1,signal1,object2,slot1);
2.3QTQWidget简介
2.3.1详细描述
QWidget类是所有用户界面对象的基类。
通俗的来讲,基本上所有的UI类都是由QWidgetQt继承出来的,而QWidget继承于QObject,大家可以查阅Qtsource即可发现一些微妙的写法,如这篇文章有详细介绍:
Qt库对象数据的声明和使用窗口层次窗口部件是用户界面的一个原子:
它从窗口系统接收鼠标、键盘和其它事件,并且在屏幕上绘制自己的表现。
每一个窗口部件都是矩形,并且它们按Z轴顺序排列的。
一个窗口部件可以被它的父窗口部件或者它前面的窗口部件盖住一部分。
QDialog是最普通的顶级窗口。
不被嵌入到一个父窗口部件的窗口部件被叫做顶级窗口部件。
通常情况下,顶级窗口部件是有框架和标题栏的窗口(尽管如果使用了一定的窗口部件标记,创建顶级窗口部件时也可能没有这些装饰。
)在Qt中,QMainWindow和和不同的QDialog的子类是最普通的顶级窗口。
一个没有父窗口部件的窗口部件一直是顶级窗口部件。
非顶级窗口部件是子窗口部件。
它们是它们的父窗口部件中的子窗口。
你通常不能在视觉角度从它们的父窗口部件中辨别一个子窗口部件。
在Qt中的绝大多数其它窗口部件仅仅作为子窗口部件才是有用的。
(当然把一个按钮作为或者叫做顶级窗口部件也是可能的,但绝大多数人喜欢把他们的按钮放到其它按钮当中,比如QDialog。
)QWidget有很多成员函数,但是它们中的一些有少量的直接功能:
例如,QWidget有一个字体属性,但是它自己从来不用。
有很多继承它的子类提供了实际的功能,比如QPushButton、QListBox和QTabDialog等等。
每一个窗口部件构造函数接受一个或两个标准参数:
1.QWidget*parent=0是新窗口部件的父窗口部件。
如果为0(默认),新的窗口部件将是一个顶级窗口部件。
如果不是,它将会使parent的一个孩子,并且被parent的几何形状所强迫(除非你指定WType_TopLevel作为窗口部件标记)。
2.3.2QWidget事件简介
基本事件:
*paintEvent()–只要窗口部件需要被重绘就被调用。
每个要显示输出的窗口部件必须实现它并且不在paintEvent()之外在屏幕上绘制是明智的。
*resizeEvent()–当窗口部件被重新定义大小时被调用。
*mousePressEvent()–当鼠标键被按下时被调用。
有六个鼠标相关事件,但是鼠标按下和鼠标释放事件是到目前为止最重要的。
当鼠标在窗口部件内或者当它使用grabMouse()来捕获鼠标时,它接收鼠标按下事件。
*mouseReleaseEvent()–当鼠标键被释放时被调用。
当窗口部件已经接收相应的鼠标按下事件时,它接收鼠标释放事件。
这也就是说如果用户在你的窗口部件内按下鼠标,然后拖着鼠标到其它某个地方,然后释放,你的窗口部件接收这个释放事件。
这里有一个例外:
如果出现在弹出菜单中,当鼠标键被按下时,这个弹出菜单立即会偷掉这个鼠标事件。
*mouseDoubleClickEvent()–和它看起来也许不太一样。
如果用户双击,窗口部件接收一个鼠标按下事件(如果他们没有拿牢鼠标,也许会出现一个或两个鼠标移动事件)、一个鼠标释放事件并且最终是这个事件。
直到你看到第二次点击是否到来之前,不能从一个双击中辨别一个点击。
(这是为什么绝大多数图形用户界面图书建议双击是单击的一个扩展,而不是一个不同行为的触发的一个原因。
)如果你的窗口部件仅仅包含子窗口部件,你也许不需要实现任何一个事件处理器。
如果你想检测在子窗口部件中的鼠标点击,请在父窗口部件的mousePressEvent()中调用子窗口部件的hasMouse()函数。
接收键盘的窗口部件需要重新实现一些更多的事件处理器:
*keyPressEvent()–只要键被按下和当键已经被按下足够长的时间可以自动重复了就被调用。
注意如果Tab和Shift+Tab键被用在焦点变换机制中,它们仅仅被传递给窗口部件。
为了强迫那些键被你的窗口部件处理,你必须重新实现QWidget:
:
event()。
*focusInEvent()–当窗口部件获得键盘焦点(假设你已经调用setFocusPolicy())时被调用。
写得好的窗口部件意味着它们能按照一种清晰但谨慎的方式来获得键盘焦点。
*focusOutEvent()–当窗口部件失去键盘焦点时被调用。
一些窗口部件也许需要实现一些不太普通的事件处理器:
*mouseMoveEvent()–只要当鼠标键被按下时鼠标移动就会被调用。
举例来说,对于拖动,这个很有用。
如果你调用setMouseTracking(TRUE),尽管没有鼠标键被按下,你也会获得鼠标移动事件。
(注意这个使用鼠标跟踪的应用程序在低下的X连接下不是很有用。
(也可以)参考拖放信息。
*keyReleaseEvent()–只要键被释放和当如果这个键是自动重复的并且被按下一段时间时就被调用。
在这种情况下窗口部件接收一个键释放事件并且对于每一个重复立即有一个键按下事件。
为了强迫那些键被你的窗口部件处理,你必须重新实现QWidget:
*wheelEvent()—当窗口部件拥有焦点时,只要用户转动鼠标滚轮就被调用。
*enterEvent()–当鼠标进入这个窗口部件屏幕空间时被调用。
*leaveEvent()–当鼠标离开这个窗口部件的屏幕空间时被调用。
*moveEvent()–当窗口部件相对于它的父窗口部件已经被移动时被调用。
*closeEvent()–当用户关闭窗口部件时(或这当close()被调用时)被调用。
这里还有一些不太明显的事件。
它们在qevent.h中被列出并且你需要重新实现event()来处理它们。
event()的默认实现处理Tab和Shift+Tab(移动键盘焦点)并且其它绝大多数事件给上面提到的一个或更多的特定处理器。
Windowflag标识关于QWidget的flag的介绍:
enumQt:
WindowTypeflagsQt:
WindowFlags这两个参数参阅官方文档。
Qt的WindowFlags有很多,实际使用时,若不关心窗口层次的话,大可不比太关心这个。
比如说在Window上做应用开发,大可只关注:
Qt:
Dialog,Qt:
Tool,Qt:
Window即可。
但若是做嵌入式开发就得好好看看这个属性,整理好这部分属性,有利于窗口管理。
着重介绍几个重要成员函数:
boolQWidget:
close()[slot]关闭这个窗口部件。
如果窗口部件被关闭,返回真,否则返回假。
首先它发送给这个窗口部件一个QCloseEvent。
如果它接收这个关闭事件,它就被隐藏了。
QWidget:
closeEvent()的默认实现是接收这个关闭事件。
当最后一个可视的顶级窗口部件被关闭,QApplication:
lastWindowClosed()信号被发射。
注意窗口的enumQt:
WidgetAttribute属性,窗口默认属性是Qt:
WA_MacOpaqueSizeGrip,设置上这个属性意味着窗口调用close()只销毁了UI想关,QWidget内还有很多内存空间没有释放,需调用delete销毁QWidget。
若需要在调用close时一并销毁窗口可以给窗口设置Qt:
WA_DeleteOnClose属性。
event(QEvent*e)[虚保护]这是主事件处理器,它处理事件e。
你可以在子类中被重新实现整个函数,但是我们建议你使用一个特定的事件处理器来替代它。
主事件首先把事件传递给所有已经被安装的事件过滤器。
如果没有过滤器中途截取这个事件,它调用一个特定的事件处理器。
键按下和释放事件被处理得和其它事件不同。
event()检查Tab和Shift+Tab并且试图适当地移动焦点。
如果没有窗口部件被焦点移入(或者键按下不是Tab或Shift+Tab),event()调用keyPressEvent()。
如果它能够把一个事件传递给没个东西,这个函数就返回真,否则如果没有任何东西想要这个事件,返回假。
也可以参考closeEvent()、focusInEvent()、focusOutEvent()、enterEvent()、keyPressEvent()、keyReleaseEvent()、leaveEvent()、mouseDoubleClickEvent()、mouseMoveEvent()、mousePressEvent()、mouseReleaseEvent()、moveEvent()、paintEvent()、resizeEvent()、QObject:
event()和QObject:
timerEvent()。
voidQWidget:
paintEvent(QPaintEvent*)[虚保护]这个事件处理器可以在子类中被重新实现来接收绘制事件。
绘制事件就是重新绘制这个窗口部件的所有部分的一个请求。
它可以是repaint()或update()的结果,或者因为这个窗口部件原来被变暗并且现在已经不再被覆盖了,或者其它很多原因。
很多窗口部件在当它们被请求时,它们很简单地重新绘制整个界面,但是一些比较慢的窗口部件需要通过仅仅绘制被请求的区域QPaintEvent:
region()进行优化。
这个速度优化不会改变结果,在事件处理过程中,绘制仅仅发生在被改变的区域中。
例如,QListView和QCanvas就是这样做的。
Qt也试图通过把多个绘制事件合并为一个来加快绘制速度。
update()被调用几次或者窗口当系统发送几次绘制事件,Qt把它们合并为一个比较大区域(请参考QRegion:
unite())的一个事件中。
repaint()不允许这样优化,所以只要可能我们建议使用update()。
当绘制事件发生,更新区域通常被擦除,所以你正在这个窗口部件的背景上绘制。
这里有一些例外并且QPaintEvent:
erased()告诉你这个窗口部件是否被擦除。
背景可以通过使用setBackgroundMode()、setPaletteBackgroundColor()或setBackgroundPixmap()来设置。
setBackgroundMode()的文档详细描述了背景,我们建议你去读一下。
voidQWidget:
raise()[槽]把这个窗口部件升高到它的父窗口部件的栈的顶部。
如果在屏幕上有与这个窗口部件重叠的兄弟,这个窗口部件将在它后来的这些兄弟之前变的可视了。
也可以参考lower()和stackUnder()