KivyMD中MapView缩放/切窗出现橙色气泡,求禁用方法
MapView缩放/切换窗口后残留橙色气泡的解决办法
我开发地图应用时,使用MapView组件,缩放地图或切换窗口后会出现无法关闭的橙色气泡,切换窗口后这些气泡还会残留。相关代码如下:
from kivy.uix.floatlayout import FloatLayout from kivy_garden.mapview import MapView from kivy.graphics import Color, Ellipse class MapWidget(FloatLayout): def __init__(self, **kwargs): super().__init__(**kwargs) self.mapview = MapView(zoom=11, lat=37.7749, lon=-122.4194) self.mapview.bind(center=self.on_map_center) self.add_widget(self.mapview) with self.mapview.canvas: Color(1, 0, 0) self.center_indicator = Ellipse(pos=(self.mapview.center_x - 5, self.mapview.center_y - 5), size=(10, 10)) def on_map_center(self, instance, value): self.center_indicator.pos = (self.mapview.center_x - 5, self.mapview.center_y - 5)
问题原因
你看到的橙色气泡是MapView自带的瓦片加载状态指示器,默认开启。直接操作mapview.canvas会和MapView的内部绘制逻辑冲突,再加上缩放、窗口切换时的重绘机制,就会导致这些指示器残留。另外,直接用center_x/center_y更新椭圆位置的方式,也可能因为坐标系转换问题,导致自定义元素和地图瓦片不同步。
解决步骤
1. 关闭内置加载指示器
初始化MapView时添加show_loading=False参数,直接禁用橙色气泡:
self.mapview = MapView(zoom=11, lat=37.7749, lon=-122.4194, show_loading=False)
2. 改用canvas.after绘制自定义元素
不要直接使用mapview.canvas,改用canvas.after层绘制,避免和MapView的内部绘制逻辑冲突:
with self.mapview.canvas.after: Color(1, 0, 0) self.center_indicator = Ellipse(pos=(self.mapview.center_x - 5, self.mapview.center_y - 5), size=(10, 10))
3. 推荐用MapMarker替代自定义椭圆
如果只是要标记地图中心,更推荐使用MapView自带的MapMarker组件,它会自动适配地图的坐标系,不会出现同步问题:
from kivy_garden.mapview import MapMarker # 在__init__中添加标记 self.marker = MapMarker(lat=37.7749, lon=-122.4194) self.mapview.add_widget(self.marker) # 绑定地图中心更新标记位置 def on_map_center(self, instance, value): self.marker.lat, self.marker.lon = self.mapview.get_latlon(*value)
完整修改后的代码
from kivy.uix.floatlayout import FloatLayout from kivy_garden.mapview import MapView, MapMarker from kivy.graphics import Color, Ellipse class MapWidget(FloatLayout): def __init__(self, **kwargs): super().__init__(**kwargs) # 禁用内置加载指示器 self.mapview = MapView(zoom=11, lat=37.7749, lon=-122.4194, show_loading=False) self.mapview.bind(center=self.on_map_center) self.add_widget(self.mapview) # 方案一:用canvas.after绘制自定义椭圆 with self.mapview.canvas.after: Color(1, 0, 0) self.center_indicator = Ellipse(pos=(self.mapview.center_x - 5, self.mapview.center_y - 5), size=(10, 10)) # 方案二:用MapMarker标记中心(二选一即可) # self.marker = MapMarker(lat=37.7749, lon=-122.4194) # self.mapview.add_widget(self.marker) def on_map_center(self, instance, value): # 对应方案一的更新逻辑 self.center_indicator.pos = (self.mapview.center_x - 5, self.mapview.center_y - 5) # 对应方案二的更新逻辑 # self.marker.lat, self.marker.lon = self.mapview.get_latlon(*value)
内容的提问来源于stack exchange,提问作者Batman Dorado
相关产品推荐
相关产品推荐

