我在更新以前固定位置的位置(实现为从BellyButton继承的自定义圆形按钮标记)时遇到问题,因此按钮的中心总是在同一个位置,而不管哪个比例或位置具有基础散点。我是这样做的,这样按钮的大小就不会随着散射而缩放。你知道吗
下面的代码是我在数据库中使用的代码的简化版本-这就是为什么它有这么多方法等。我需要belly_pos
和belly_text
将这些方法写入数据库。你知道吗
到目前为止,我发现在缩放和拖动散布时,Marker.pos
对于maker实例保持在正确的位置,但我不知道为什么-因为我正在有效地更新belly_pos
,而不是Marker.pos
。我在画布上加了一些线条来更好地说明它。你知道吗
考虑以下代码(您需要将一些图片放置为'地图.jpg“到同一文件夹):
from kivy.app import App
from kivy.lang import Builder
from kivy.logger import Logger as logging
import kivy.metrics as kvmetrics
from kivy.uix.widget import Widget
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.behaviors.button import ButtonBehavior
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.properties import StringProperty
from kivy.properties import ListProperty
from kivy.properties import NumericProperty
kivy_lang = '''
<ProjectMap>:
BoxLayout:
id: main_box
BellyButton:
id: add_new
belly_pos: (root.size[0]-self.size[0]/2,root.y+self.size[1]/2)
belly_text: "+"
on_press: root.add_marker()
<MapScatter>:
scatter_pos: imgscatter.pos
scatter_scale: imgscatter.scale
Scatter:
id: imgscatter
size_hint: None, None
size: img.size
auto_bring_to_front: False
do_rotation: False
Image:
id: img
source: root.map_path
# pos: imgscatter.pos
size: self.texture_size
canvas.before:
Color:
rgba: 1, 1, 1, 1
BorderImage:
border: (root.image_border,root.image_border,root.image_border,root.image_border)
size: (self.width+2*root.image_border,self.height+2*root.image_border)
pos: (-1*root.image_border,-1*root.image_border)
<BellyButton>:
size_hint: None, None
size: (belly_label.texture_size[1]*1.2, belly_label.texture_size[1]*1.2)
center: self.belly_pos
canvas.after:
Color:
rgba: 0,1,0,1
Line:
points: self.x, self.y, self.x+10, self.y+10
canvas:
Color:
rgba: self.belly_color
Ellipse:
pos: self.pos
size: self.size
Line:
points: self.x, self.y, self.center[0], self.center[1]
Label:
id: belly_label
size: self.texture_size
font_size: sp(app.gui_multiplier)
pos: [root.center_x-self.size[0]/2,root.center_y-self.size[1]/2]
text: root.belly_text
<Marker>:
'''
class BellyButton(ButtonBehavior, Widget):
belly_pos = ListProperty([0,0])
belly_text = StringProperty('#')
belly_color = ListProperty([1,0,0,1])
def __init__(self, *args, **kwargs):
super(BellyButton, self).__init__(*args,**kwargs)
class Marker(BellyButton):
location = [0,0]
def __init__(self, *args, **kwargs):
super(Marker, self).__init__(*args,**kwargs)
#self.center = self.location
def update_pos(self, offset, scale):
self.belly_pos = [offset[0] +self.size[0]/2 +(self.location[0]) * scale, offset[1]+ self.size[1]/2+(self.location[1]) * scale]
logging.info('''info: updated belly_pos context::
current scatter pos: {}
current scatter scale: {}
saved marker location: {}
calculated belly_pos: {}'''.format(offset,scale,self.location, self.belly_pos))
return self.belly_pos
def save_pos(self,offset,scale):
self.location = [(self.location[0] - offset[0])/scale, (self.location[1] - offset[1])/scale]
return self.location
class ProjectMap(FloatLayout):
def __init__(self,*args,**kwargs):
FloatLayout.__init__(self,**kwargs)
self.markers = []
self.load_map()
def load_map(self,**kwargs):
self.ids.main_box.clear_widgets()
self.ids.add_new.disabled = False
self.current_map = MapScatter('map.jpg')
self.current_map.bind(scatter_pos=self.transfer_pos)
self.current_map.bind(scatter_scale=self.transfer_pos)
for marker in self.markers:
self.current_map.add_widget(marker)
self.ids.main_box.add_widget(self.current_map)
img_bigger_dim = self.current_map.ids.img.texture_size.index(max(self.current_map.ids.img.texture_size))
self.current_map.ids.imgscatter.scale = 0.9 * Window.size[img_bigger_dim] / self.current_map.ids.imgscatter.size[0]
self.current_map.ids.imgscatter.scale_min = 0.5 * self.current_map.ids.imgscatter.scale
self.current_map.ids.imgscatter.center = (Window.size[0]/2,Window.size[1]/2)
def transfer_pos(self, *args, **kwargs):
for no in range(0,len(self.current_map.children)-1):
self.current_map.children[no].update_pos(self.current_map.scatter_pos,self.current_map.scatter_scale)
def add_marker(self,*args,**kwargs):
# self.new_marker.destroy()
self.new_marker = Marker()
self.place_marker_hint()
def place_marker_hint(self,*args,**kwargs):
self.marker_hint = BellyButton()
self.marker_hint.belly_color[3] = 0.5
self.marker_hint.belly_pos = self.center
self.marker_hint.bind(on_press=self.save_marker)
self.add_widget(self.marker_hint)
self.ids.add_new.disabled = True
def calc_new_marker_pos(self):
self.new_marker.location = self.center
self.new_marker.save_pos(self.current_map.scatter_pos,self.current_map.scatter_scale)
logging.info('''info: marker saved location context::
current window center: {}
current window scatterMap scatter_pos: {}
current window scatterMap scatter_scale: {}
current scatterMap scatter size: {}
current scatterMap img size: {}
marker size: {}
saved marker location: {}
calculated new Marker belly_pos(its center): {}
'''. format(self.center, self.current_map.scatter_pos, self.current_map.scatter_scale, self.current_map.ids.imgscatter.size, self.current_map.ids.img.size, self.new_marker.size, self.new_marker.location, self.new_marker.belly_pos ))
def save_marker(self, *args):
self.calc_new_marker_pos()
self.new_marker.belly_text = str(len(self.current_map.children)-1)
self.markers.append(self.new_marker)
self.current_map.clear_widgets()
self.remove_widget(self.marker_hint)
self.load_map()
class MapScatter(FloatLayout):
map_path = StringProperty('')
scatter_pos = ListProperty([0,0])
scatter_scale = NumericProperty(1.0)
image_border = NumericProperty(1.0)
def __init__(self, map_path,*args,**kwargs):
FloatLayout.__init__(self,*args,**kwargs)
self.map_path = map_path
self.image_border = kvmetrics.sp(app.gui_multiplier)*0.1
class MyApp(App):
gui_multiplier = NumericProperty(30)
def build(self):
Builder.load_string(kivy_lang)
return ProjectMap()
def on_pause(self):
return True
if __name__ == '__main__':
app = MyApp()
app.run()
目前没有回答
相关问题 更多 >
编程相关推荐