Python kivy花园mapview经度和纬度不会更新

时间:2018-08-13 15:26:16

标签: python kivy kivy-language

我正在尝试使用Kivy Garden中的MapView小部件,但标记的位置不会更新。我已将MapViewMapMarker添加到main.kv文件中。它们具有属性latlon。我试图通过使用latitudelongitude为他们分配变量main.pyapp.latitude形成app.longitude变量。

在我的main.py内部,我正在on_start方法内部使用一个更新函数。更新函数仅调用两个辅助函数,这些辅助函数获取经度和纬度坐标(目前仅是随机值)。

问题是我在运行代码时mapview和标记不会更新。我在做什么错了?

# section of main.kv
MapView:
    id: map_view
    zoom: 17
    lat: app.latitude
    lon: app.longitude
    MapMarker:
        id: map_view_marker
        lat: app.latitude
        lon: app.longitude

这是main.py的部分

# main.py
… 
class MainApp(App):
…
    # map parameters
    latitude = 50
    longitude = 3

    # Getting latitude and longitude (at the moment just random stuff
    def get_gps_latitude(self):
        self.latitude = self.decimal_precision(0.01 * random.random() + 50.6394, DECIMAL_PRECISION)
        return self.latitude # rounding

    def get_gps_longitude(self):
        self.longitude = self.decimal_precision(0.01 * random.random() + 50.6394, DECIMAL_PRECISION)
        return self.longitude

    def update(self, _):
        self.latitude = self.get_gps_latitude()
        self.longitude = self.get_gps_longitude()

    def on_start(self):
        Clock.schedule_interval(self.update, 1)

更新:添加我的kv文件的标题。

#:kivy 1.10.1
#:import Toolbar kivymd.toolbar.Toolbar
#:import MDNavigationDrawer kivymd.navigationdrawer.MDNavigationDrawer
#:import NavigationLayout kivymd.navigationdrawer.NavigationLayout
#:import NavigationDrawerDivider kivymd.navigationdrawer.NavigationDrawerDivider
#:import NavigationDrawerToolbar kivymd.navigationdrawer.NavigationDrawerToolbar
#:import NavigationDrawerSubheader kivymd.navigationdrawer.NavigationDrawerSubheader
#:import MDTextField kivymd.textfields.MDTextField
#:import MDSwitch kivymd.selectioncontrols.MDSwitch
#:import labels application.labels
#:import MapView kivy.garden.mapview
#:import MapMarkerPopup kivy.garden.mapview

NavigationLayout:
    id: nav_layout
    MDNavigationDrawer:
        id: nav_drawer
        NavigationDrawerToolbar:
            title: labels.NAVIGATION
        NavigationDrawerIconButton:
            icon: 'checkbox-blank-circle'
            text: labels.OPERATING_MODE
            on_release: app.root.ids.scr_mngr.current = 'operating_mode'
    BoxLayout:
        orientation: 'vertical'
        halign: "center"
        Toolbar:
            id: toolbar
            title: labels.APPLICATION_NAME
            md_bg_color: app.theme_cls.primary_color
            background_palette: 'Primary'
            background_hue: '500'
            left_action_items: [['menu', lambda x: app.root.toggle_nav_drawer()]]
            #right_action_items: [['dots-vertical', lambda x: app.root.toggle_nav_drawer()]]
        ScreenManager:
            id: scr_mngr
            Screen:
                name: 'operating_mode'
                BoxLayout:
                    orientation: "vertical"
                    padding: dp(48)
                    width: dp(100)
                    spacing: 24
                    BoxLayout:
                        orientation: "horizontal"
                        spacing: 24
                        BoxLayout:
                            orientation: "horizontal"
                            MapView:
                                id: map_view
                                zoom: 10
                                lat: app.latitude
                                lon: app.longitude
                                MapMarkerPopup:
                                    id: map_view_marker
                                    lat: app.latitude
                                    lon: app.longitude

1 个答案:

答案 0 :(得分:1)

您只能在使用Properties时进行绑定,在这种情况下,纬度和经度不是“属性”,因此它们不会产生更改。在这种情况下,您必须使用NumericProperty

另一方面,lat中的lonMapView只读的,因此分配:

MapView:
    id: map_view
    zoom: 17
    lat: app.latitude  # <---
    lon: app.longitude # <---

设置起始值,但您无法对其进行更新,要更新MapView的中心,必须使用center_on()

main.py

from kivy.app import App
from kivy.clock import Clock
from kivy.properties import NumericProperty
import random

DECIMAL_PRECISION = 2

class MainApp(App):
    # map parameters
    latitude = NumericProperty(50)
    longitude = NumericProperty(3)

    def decimal_precision(self, val, precision):
        # foo process
        return val

    # Getting latitude and longitude (at the moment just random stuff
    def get_gps_latitude(self):
        self.latitude = self.decimal_precision(0.01 * random.random() + 50.6394, DECIMAL_PRECISION)
        return self.latitude # rounding

    def get_gps_longitude(self):
        self.longitude = self.decimal_precision(0.01 * random.random() + 50.6394, DECIMAL_PRECISION)
        return self.longitude

    def update(self, _):
        self.latitude = self.get_gps_latitude()
        self.longitude = self.get_gps_longitude()
        self.root.center_on(self.latitude, self.longitude)

    def on_start(self):
        Clock.schedule_interval(self.update, 1)

if __name__ == '__main__':
    MainApp().run()

main.kv

#:import MapView kivy.garden.mapview.MapView

# section of main.kv
MapView:
    id: map_view
    zoom: 17
    lat: app.latitude
    lon: app.longitude
    MapMarker:
        id: map_view_marker
        lat: app.latitude
        lon: app.longitude

更新

map_view是非常深层次结构的根子级,因此要以简单的方式访问它,就可以创建一个属性:map_view: map_view,然后我们通过self.root.map_view进行访问:

*。kv

NavigationLayout:
    id: nav_layout
    map_view: map_view # <---

*。py

def update(self, _):
    self.latitude = self.get_gps_latitude()
    self.longitude = self.get_gps_longitude()
    self.root.map_view.center_on(self.latitude, self.longitude)