在Qt中加载百度地图需要用到网络浏览器,在此采用webEngine
模块,然后用webchannel进行qt与HTML/JavaScript的交互。
需求描述:软件加载百度地图,用鼠标在地图上选点,并进行标号,每次加1,最后连成一条路径,为后期工作做准备。
var map = new BMap.Map("map_demo",mapOptions); // 设置街道图为底图
var point = new BMap.Point(120.393751, 36.065743); // 创建点坐标
map.centerAndZoom(point,13); // 初始化地图,设置中心点坐标和地图级别
用addEventListener("click",function(e))
对点击事件进行监听,参数e
会返回当前点的地理位置,然后在此处用Marker
添加标记,在实现每次标记加1时,因为标记本身是一个图片,因此可以考虑对标记加标签(定义一个全局的i
,每点击一次加1),然后调整下位置(为了美观),背景设置为透明,基本就可以实现所要的效果。标签的颜色和背景可以使用Label
类下的setStyle
方法设置:
label.setStyle({
color:"white",
backgroundColor:"0",
border:"0";
fontsize:"13px"
});
创建一个全局空数组,在上一步中监听点击事件,参数e
返回位置点,将此点push
到数组中,在生成轨迹时将数组序列直接传入Polyline
,然后map.addOverlay(polyline)
即可加载标签。
具体的类和方法参见百度地图JavaScript API 2.0和示例Demo
用wenEngine全屏显示地图时的代码:
//mainwidow中的函数
view=new QWebEngineView(this);
view->load(url);
view->show();
添加:
void MainWindow::resizeEvent(QResizeEvent *)
{
view->resize(this->size());
}
widget
中显示在UI设计界面,我的qt5.9版本是找不到wenEngineView
组件的,解决方法:在ui设计页面,拖入widgets
控件,然后提升为QWebengineView
,如图所示:
在mainwindow函数中进行webengine初始化:
QWebEnginePage *page=new QWebEnginePage(this);
QWebChannel *channel=new QWebChannel(this);
page->load(url);
page->setWebChannel(channel);
ui->webEngine->setPage(page);
新版的Qt摒弃了webkit,采用webengine,在交互上简单了很多,例如生成路径
按钮的槽函数:
void MainWindow::on_generatetrack_clicked()
{
QString cmd="generate_track()";
ui->webengine->page()->runJavaScript(cmd);
}
其中generate_track()
为html文件中的函数,只需要一条语句即可实现交互。
最终效果如图:
功能:实现小车沿路径运动
有两种方案:
第二种方案适合于路径点很密集,很多的情况,才能看出效果。由于这个项目是采用鼠标选几个位置,因此适合采用第一种方案。
实现部分:
<script type="text/javascript" src="tools/LuShu_min.js">script>
generate_track
函数里lushu=new BMapLib.LuShu(map,track_point,{
icon:icon1,//图标可以自己添加,也可以默认为百度的红色标注小气球
speed:3000,
autoView:false,
enableRotation:true
});
lushu.start();
功能:对已经选择的路径点通过输入经纬度进行修改(生成路径前后均可修改)
首先在Qt中添加以下代码(前提是在界面中设置好文本框和修改
按钮):
void MainWindow::on_modify_clicked()
{
QString number=ui->orderNumber->text();
QString lng=ui->lngEdit->text();
QString lat=ui->latEdit->text();
QString cmd=QString("modifyMarker(\"%1\",\"%2\",\"%3\")").arg(number).arg(lng).arg(lat); //modifyMaker是html文件中的函数
ui->webengine->page()->runJavaScript(cmd);
}
在html文件中添加:
function modifyMarker(number,lng,lat){
allMarker=map.getOverlays(); //保存所有标注
var newpoint=new BMap.Point(lng,lat);
allMarker[number-1].setPosition(newpoint);
track_point[number-1]=newpoint;
if(allMarker[allMarker.length-1].toString()!="[object Marker]"){ //看array中最后一个元素是不是polyline
map.removeOverlay(polyline); //来判断生成路径之前
generate_track(); //还是生成路径之后修改路径点
}
}
由于没有系统学习过JavaScript,其中if中的判断语句参考了下面图片中的方法,意思就是判断最后一个覆盖物是不是Marker
对象。
在getOverlays()
后不知道为什么多一个隐藏的标注,所以在选路径点时先清理一次所有的标注,即在选路径点
的函数中首先添加:
map.clearOverlays();