










近期在疯狂测试地图组件,在不断的放大和缩小地图过程中,一开始发现会有白色背景闪烁,尽管是一闪而过,总体感觉还是不大好,最后发现是在重新刷新界面的时候,有一次是空白透明的背景图,也触发了一次绘制,将这个绘制关闭就好,这个现象在加载本地文件的时候非常明显。关闭之后白色背景是没有了,又出来新的问题,发现缩放滑块会有个白色背景,通过打印调试发现,父类的painter触发了子类的painter导致的,而这个缩放滑块在默认绘制的时候,会以系统的背景颜色绘制,然后才是自身的绘制,本来控件是透明背景的,之前由于这个背景和闪烁的背景颜色一致,所以看不清,现在把瓦片地图的白色背景去掉以后,就很明显了。
着手解决这个问题,用了浑身解数,包括设置setAttribute(Qt::WA_OpaquePaintEvent)或者setAttribute(Qt::WA_NoSystemBackground)等,测试了十几种方法,依然无效,这个该死的白色背景还是会在一瞬间显示,也就在缩放级别变化的时候触发,后面想起来有一个setUpdatesEnabled属性可以临时禁用控件绘制,于是在缩放变化前,主动设置m_zoom_control_slider.setUpdatesEnabled(false),然后等到整张瓦片地图绘制完成的时候,再m_zoom_control_slider.setUpdatesEnabled(true)就可以了,核心原理就是在中途绘制期间禁止这个缩放滑块的绘制。但是又不能一直禁用,因为还有缩放级别要显示在滑块上,所以要在合适的时机重新启用绘制。


#include "mapwidget.h"
#include "maphelper.h"
#include "imagemanager.h"
#include "layermapadapter.h"
#include "overlayhelper.h"
MapWidget::MapWidget(QWidget *parent) : QWidget(parent)
{
tileSource = TileSource_Tian;
tileType = TileType_Street;
offline = false;
offlinePath = ".";
cacheExpiry = 0;
cachePath = "";
//实例化地图控件
mapControl = new QMapControl(this);
//mapControl->setMouseButtonLeft(QMapControl::MouseButtonMode::DrawBox, true);
connect(mapControl, SIGNAL(mouseEventPressCoordinate(QMouseEvent *, PointWorldCoord)), this, SLOT(mouseEventPressCoordinate(QMouseEvent *, PointWorldCoord)));
connect(mapControl, SIGNAL(mouseEventMoveCoordinate(QMouseEvent *, PointWorldCoord, PointWorldCoord)), this, SLOT(mouseEventMoveCoordinate(QMouseEvent *, PointWorldCoord, PointWorldCoord)));
connect(mapControl, SIGNAL(mouseEventReleaseCoordinate(QMouseEvent *, PointWorldCoord, PointWorldCoord)), this, SLOT(mouseEventReleaseCoordinate(QMouseEvent *, PointWorldCoord, PointWorldCoord)));
}
void MapWidget::setFlag(const QString &flag)
{
mapControl->setFlag(flag);
this->setObjectName(QString("MapWidget_%1").arg(flag));
}
void MapWidget::resizeEvent(QResizeEvent *)
{
QSize size = this->size();
mapControl->setGeometry(0, 0, size.width(), size.height());
//可以加大后面的值/会缓存更多的瓦片
mapControl->setViewportSize(size + QSize(0, 0));
}
void MapWidget::mouseEventPressCoordinate(QMouseEvent *mouse_event, PointWorldCoord press_coordinate)
{
emit receivePoint(press_coordinate.longitude(), press_coordinate.latitude());
}
void MapWidget::mouseEventMoveCoordinate(QMouseEvent *mouse_event, PointWorldCoord press_coordinate, PointWorldCoord current_coordinate)
{
emit receivePoint(current_coordinate.longitude(), current_coordinate.latitude());
}
void MapWidget::mouseEventReleaseCoordinate(QMouseEvent *mouse_event, PointWorldCoord press_coordinate, PointWorldCoord release_coordinate)
{
}
void MapWidget::load()
{
//清空缓存图片
mapControl->clearImage();
//清空所有图层
mapControl->clearLayers();
//启用缩放背景
mapControl->enableScaledBackground(false);
//添加瓦片图层
TileHelper::loadTile(mapControl, tileSource, tileType, offline);
//添加覆盖物图层
overlayLayer = std::make_shared<LayerOverlay>("overlayLayer");
overlayLayer->setMouseEventsEnabled(false);
mapControl->addLayer(overlayLayer);
}
void MapWidget::zoomIn()
{
mapControl->zoomIn();
}
void MapWidget::zoomOut()
{
mapControl->zoomOut();
}
void MapWidget::requestRedraw()
{
mapControl->requestRedraw();
}
int MapWidget::getZoom()
{
return mapControl->getCurrentZoom();
}
void MapWidget::setZoom(int zoom)
{
mapControl->setZoom(zoom);
}
QPointF MapWidget::getCenter()
{
RectWorldCoord coord = mapControl->getViewportRect();
return coord.rawRect().center();
}
void MapWidget::setCenter(qreal lng, qreal lat)
{
mapControl->setMapFocusPoint(PointWorldCoord(lng, lat));
}
QRectF MapWidget::getViewportRect()
{
return mapControl->getViewportRect().rawRect();
}
QMapControl *MapWidget::getMapControl()
{
return this->mapControl;
}
std::shared_ptr<LayerOverlay> MapWidget::getOverlayLayer()
{
return this->overlayLayer;
}
QMultiMap<QString, std::shared_ptr<OverlayBase>> &MapWidget::getOverlays()
{
return this->overlays;
}
void MapWidget::enableScalebar(bool visible)
{
mapControl->enableScalebar(visible);
}
void MapWidget::enableCrosshairs(bool visible)
{
mapControl->enableCrosshairs(visible);
}
void MapWidget::enableZoomControls(bool visible)
{
mapControl->enableZoomControls(visible);
}
void MapWidget::enableDragging(bool enable)
{
mapControl->enableDragging(enable);
}
void MapWidget::enableKeyboard(bool enable)
{
mapControl->enableKeyboard(enable);
}
void MapWidget::enableScrollWheelZoom(bool enable)
{
mapControl->enableScrollWheelZoom(enable);
}
void MapWidget::enableDoubleClickZoom(bool enable)
{
mapControl->enableDoubleClickZoom(enable);
}
void MapWidget::enableMouseTracking(bool enable)
{
mapControl->setMouseTracking(enable);
}
void MapWidget::setTileSource(TileSource tileSource)
{
this->tileSource = tileSource;
}
void MapWidget::setTileType(TileType tileType)
{
this->tileType = tileType;
}
void MapWidget::setOffline(bool offline)
{
this->offline = offline;
}
void MapWidget::setOfflinePath(const QString &offlinePath)
{
this->offlinePath = offlinePath;
}
void MapWidget::setCacheExpiry(int cacheExpiry)
{
if (this->cacheExpiry != cacheExpiry) {
this->cacheExpiry = cacheExpiry;
mapControl->enablePersistentCache(cachePath, std::chrono::minutes(cacheExpiry));
}
}
void MapWidget::setCachePath(const QString &cachePath)
{
if (this->cachePath != cachePath) {
this->cachePath = cachePath;
mapControl->enablePersistentCache(cachePath, std::chrono::minutes(cacheExpiry));
}
}
void MapWidget::setStyle(const QColor &color)
{
mapControl->setStyle(color);
}
void MapWidget::savePixmap(const QString &fileName, bool full, const QList<QPointF> &points)
{
MapHelper::savePixmap(mapControl, fileName, full, points);
}
void MapWidget::setAutoView(const QRectF &rect)
{
MapHelper::setAutoView(mapControl, rect);
}
void MapWidget::setAutoView(const QString &points)
{
MapHelper::setAutoView(mapControl, MapHelper::getRect(points));
}
void MapWidget::setAutoView(const QList<QPointF> &points)
{
MapHelper::setAutoView(mapControl, MapHelper::getRect(points));
}
void MapWidget::addPoint(const QString &flag, qreal lng, qreal lat, const QColor &color, int width)
{
OverlayHelper::addPoint(this, flag, lng, lat, color, width);
}
void MapWidget::updatePoint(const QString &flag, qreal lng, qreal lat, const QColor &color, int width)
{
OverlayHelper::updatePoint(this, flag, lng, lat, color, width);
}
QPointF MapWidget::getPointCoord(const QString &flag)
{
return OverlayHelper::getPointCoord(this, flag);
}
void MapWidget::addLabel(const QString &flag, qreal lng, qreal lat, const QColor &color, const QString &text, int align, int size)
{
OverlayHelper::addLabel(this, flag, lng, lat, color, text, align, size);
}
void MapWidget::updateLabel(const QString &flag, qreal lng, qreal lat, const QColor &color, const QString &text, int align, int size)
{
OverlayHelper::updateLabel(this, flag, lng, lat, color, text, align, size);
}
QPointF MapWidget::getLabelPara(const QString &flag, QString *text)
{
return OverlayHelper::getLabelPara(this, flag, text);
}
OverlayBase *MapWidget::addMarker(const QString &flag, qreal lng, qreal lat, const QString &file, const QPixmap &pixmap, int rotate, int align)
{
return OverlayHelper::addMarker(this, flag, lng, lat, file, pixmap, rotate, align);
}
OverlayBase *MapWidget::updateMarker(const QString &flag, qreal lng, qreal lat, const QString &file, const QPixmap &pixmap, int rotate, int align)
{
return OverlayHelper::updateMarker(this, flag, lng, lat, file, pixmap, rotate, align);
}
QPixmap MapWidget::getMarkerPara(const QString &flag, qreal *lng, qreal *lat, int *rotate, int *align)
{
return OverlayHelper::getMarkerPara(this, flag, lng, lat, rotate, align);
}
void MapWidget::addPolyline(const QString &flag, const QStringList &points, const QColor &color, int width)
{
OverlayHelper::addPolyline(this, flag, MapHelper::getPoints(points), color, width);
}
void MapWidget::addPolyline(const QString &flag, const QList<QPointF> &points, const QColor &color, int width)
{
OverlayHelper::addPolyline(this, flag, MapHelper::getPoints(points), color, width);
}
void MapWidget::updatePolyline(const QString &flag, const QStringList &points, const QColor &color, int width)
{
OverlayHelper::updatePolyline(this, flag, MapHelper::getPoints(points), color, width);
}
void MapWidget::updatePolyline(const QString &flag, const QList<QPointF> &points, const QColor &color, int width)
{
OverlayHelper::updatePolyline(this, flag, MapHelper::getPoints(points), color, width);
}
QList<QPointF> MapWidget::getPolylinePoints(const QString &flag)
{
return OverlayHelper::getPolylinePoints(this, flag);
}
void MapWidget::addPolylineData(const QString &flag, qreal lng, qreal lat)
{
OverlayHelper::addPolylineData(this, flag, lng, lat);
}
void MapWidget::setPolylineData(const QString &flag, const QList<QPointF> &points)
{
OverlayHelper::setPolylineData(this, flag, MapHelper::getPoints(points));
}
void MapWidget::addPolygon(const QString &flag, const QStringList &points, const QColor &color, int width, const QColor &bgColor)
{
OverlayHelper::addPolygon(this, flag, MapHelper::getPoints(points), color, width, bgColor);
}
void MapWidget::addPolygon(const QString &flag, const QList<QPointF> &points, const QColor &color, int width, const QColor &bgColor)
{
OverlayHelper::addPolygon(this, flag, MapHelper::getPoints(points), color, width, bgColor);
}
void MapWidget::updatePolygon(const QString &flag, const QStringList &points, const QColor &color, int width, const QColor &bgColor)
{
OverlayHelper::updatePolygon(this, flag, MapHelper::getPoints(points), color, width, bgColor);
}
void MapWidget::updatePolygon(const QString &flag, const QList<QPointF> &points, const QColor &color, int width, const QColor &bgColor)
{
OverlayHelper::updatePolygon(this, flag, MapHelper::getPoints(points), color, width, bgColor);
}
QList<QPointF> MapWidget::getPolygonPoints(const QString &flag)
{
return OverlayHelper::getPolygonPoints(this, flag);
}
void MapWidget::addRectangle(const QString &flag, const QPointF &topLeft, const QPointF &bottomRight, const QColor &color, int width, const QColor &bgColor)
{
QList<QPointF> points;
QRectF rect = MapHelper::getRect(topLeft, bottomRight);
points << rect.topLeft() << rect.topRight() << rect.bottomRight() << rect.bottomLeft();
this->addPolygon(flag, points, color, width, bgColor);
}
void MapWidget::updateRectangle(const QString &flag, const QPointF &topLeft, const QPointF &bottomRight, const QColor &color, int width, const QColor &bgColor)
{
QList<QPointF> points;
if (!topLeft.isNull() && !bottomRight.isNull()) {
QRectF rect = MapHelper::getRect(topLeft, bottomRight);
points << rect.topLeft() << rect.topRight() << rect.bottomRight() << rect.bottomLeft();
}
this->updatePolygon(flag, points, color, width, bgColor);
}
QRectF MapWidget::getRectangleRect(const QString &flag)
{
QList<QPointF> points = this->getPolygonPoints(flag);
return QRectF(points.at(0), points.at(1));
}
void MapWidget::addBoundary(const QString &flag, const QString &points, const QColor &color, int width, const QColor &bgColor)
{
OverlayHelper::addBoundary(this, flag, points, color, width, bgColor);
}
void MapWidget::addCircle(const QString &flag, qreal lng, qreal lat, qreal radius, const QColor &color, int width, const QColor &bgColor)
{
OverlayHelper::addCircle(this, flag, lng, lat, radius, color, width, bgColor);
}
void MapWidget::updateCircle(const QString &flag, qreal lng, qreal lat, qreal radius, const QColor &color, int width, const QColor &bgColor)
{
OverlayHelper::updateCircle(this, flag, lng, lat, radius, color, width, bgColor);
}
QRectF MapWidget::getCirclePara(const QString &flag, qreal *lng, qreal *lat, qreal *radius)
{
return OverlayHelper::getCirclePara(this, flag, lng, lat, radius);
}
void MapWidget::addWidget(const QString &flag, qreal lng, qreal lat, QWidget *form)
{
OverlayHelper::addWidget(this, flag, lng, lat, form);
}
void MapWidget::updateWidget(const QString &flag, qreal lng, qreal lat)
{
OverlayHelper::updateWidget(this, flag, lng, lat);
}
QWidget *MapWidget::getWidget(const QString &flag)
{
return OverlayHelper::getWidget(this, flag);
}
void MapWidget::setOverlayVisible(bool visible)
{
OverlayHelper::setOverlayVisible(this, visible);
}
void MapWidget::setOverlayVisible(const QString &flag, bool visible)
{
OverlayHelper::setOverlayVisible(this, flag, visible);
}
void MapWidget::deleteOverlay(const QString &flag)
{
OverlayHelper::deleteOverlay(this, flag);
}
void MapWidget::deleteGroup(const QString &group)
{
OverlayHelper::deleteGroup(this, group);
}
void MapWidget::clearOverlay()
{
OverlayHelper::clearOverlay(this);
}
void MapWidget::setZIndex(const QString &flag, int zindex)
{
OverlayHelper::setZIndex(this, flag, zindex);
}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。