使用 Kivy ScatterLayout 进行缩放不符合预期
Scale with Kivy ScatterLayout Doesn't Behave as Expected
我想放大和缩小一组小部件。我也想滚动。我尝试使用 ScrollView
作为根小部件和 ScatterLayout
作为我想要放大和缩小的 child.The 小部件来完成此操作 children ScatterLayout
。这未按预期运行。这是一个最小版本。
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.scatter import Scatter
from kivy.uix.scatterlayout import ScatterLayout
from kivy.uix.scrollview import ScrollView
kv = '''
#:kivy 1.11.1
<MyScatter>:
do_translation_y: False
do_rotation: False
do_scale: False
canvas:
Color:
hsv: .1, 1, .5
Rectangle:
size: 100, 100
<ScrollView>:
size_hint: None, None
size: 640, 480
pos_hint: {'center_x': .5, 'center_y': .5}
scroll_type: ['bars']
bar_width: 10
bar_inactive_color: self.bar_color
canvas:
Color:
rgb: 1, 0, 0
Rectangle:
pos: self.pos
size: self.size
<MyScatterLayout>:
size_hint: None, None
size: 1280, 720
do_translation: False
do_rotation: False
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
canvas:
Color:
rgb: 0, 0, 1
Rectangle:
pos: self.pos
size: self.size
'''
Builder.load_string(kv)
class MyScatter(Scatter):
pass
class MyScatterLayout(ScatterLayout):
pass
class MyApp(App):
def build(self):
layout = MyScatterLayout()
layout.add_widget(MyScatter())
root = ScrollView()
root.add_widget(layout)
return root
if __name__ == '__main__':
MyApp().run()
缩小时,ScatterLayout
的 child 最终会超出布局边界。我希望所有 children 都保持在布局范围内,无论转换是什么。我做错了什么?
与问题相切:当我缩小到足以使 ScatterLayout 小于 ScrollView
时,滚动会将 ScatterLayout
捕捉到原点(左下角)。根据 ScrollView docs 看起来 ScrollView
的 child 应该比 ScrollView
本身大。我假设为了防止这种情况发生,我需要在滚动时增加 ScatterLayout
的大小。
不确定这是否与问题有关,但 ScatterLayout
是 Scatter
的子类,因此其 canvas 指令必须在本地坐标中。
<MyScatterLayout>:
...
canvas:
Color:
rgb: 0, 0, 1
Rectangle:
pos: 0, 0 # <- shold be this
size: self.size
并且您不应该为 ScrollView
编写任何规则,因为它会影响可能存在于您的代码之外的所有实例。因此,改为定义一个子类并为其编写规则。
class MyScrollView(ScrollView):
pass
<MyScrollView>:
...
您必须缩放 ScatterLayout
的大小以使子项的位置保持一致。我还加入了 .
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.scatter import Scatter
from kivy.uix.scatterlayout import ScatterLayout
from kivy.uix.scrollview import ScrollView
kv = '''
#:kivy 1.11.1
<MyScatter>:
do_translation_y: False
do_rotation: False
do_scale: False
canvas:
Color:
hsv: .1, 1, .5
Rectangle:
size: 100, 100
<MyScrollView>:
size_hint: None, None
size: 640, 480
pos_hint: {'center_x': .5, 'center_y': .5}
scroll_type: ['bars']
bar_width: 10
bar_inactive_color: self.bar_color
canvas:
Color:
rgb: 1, 0, 0
Rectangle:
pos: self.pos
size: self.size
<MyScatterLayout>:
size_hint: None, None
size: 1280 * self.scale, 720 * self.scale # this is the correction
do_translation: False
do_rotation: False
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
canvas:
Color:
rgb: 0, 0, 1
Rectangle:
pos: 0, 0
size: self.size
'''
Builder.load_string(kv)
class MyScatter(Scatter):
pass
class MyScatterLayout(ScatterLayout):
pass
class MyScrollView(ScrollView):
pass
class MyApp(App):
def build(self):
layout = MyScatterLayout()
layout.add_widget(MyScatter())
root = MyScrollView()
root.add_widget(layout)
return root
if __name__ == '__main__':
MyApp().run()
我想放大和缩小一组小部件。我也想滚动。我尝试使用 ScrollView
作为根小部件和 ScatterLayout
作为我想要放大和缩小的 child.The 小部件来完成此操作 children ScatterLayout
。这未按预期运行。这是一个最小版本。
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.scatter import Scatter
from kivy.uix.scatterlayout import ScatterLayout
from kivy.uix.scrollview import ScrollView
kv = '''
#:kivy 1.11.1
<MyScatter>:
do_translation_y: False
do_rotation: False
do_scale: False
canvas:
Color:
hsv: .1, 1, .5
Rectangle:
size: 100, 100
<ScrollView>:
size_hint: None, None
size: 640, 480
pos_hint: {'center_x': .5, 'center_y': .5}
scroll_type: ['bars']
bar_width: 10
bar_inactive_color: self.bar_color
canvas:
Color:
rgb: 1, 0, 0
Rectangle:
pos: self.pos
size: self.size
<MyScatterLayout>:
size_hint: None, None
size: 1280, 720
do_translation: False
do_rotation: False
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
canvas:
Color:
rgb: 0, 0, 1
Rectangle:
pos: self.pos
size: self.size
'''
Builder.load_string(kv)
class MyScatter(Scatter):
pass
class MyScatterLayout(ScatterLayout):
pass
class MyApp(App):
def build(self):
layout = MyScatterLayout()
layout.add_widget(MyScatter())
root = ScrollView()
root.add_widget(layout)
return root
if __name__ == '__main__':
MyApp().run()
缩小时,ScatterLayout
的 child 最终会超出布局边界。我希望所有 children 都保持在布局范围内,无论转换是什么。我做错了什么?
与问题相切:当我缩小到足以使 ScatterLayout 小于 ScrollView
时,滚动会将 ScatterLayout
捕捉到原点(左下角)。根据 ScrollView docs 看起来 ScrollView
的 child 应该比 ScrollView
本身大。我假设为了防止这种情况发生,我需要在滚动时增加 ScatterLayout
的大小。
不确定这是否与问题有关,但 ScatterLayout
是 Scatter
的子类,因此其 canvas 指令必须在本地坐标中。
<MyScatterLayout>:
...
canvas:
Color:
rgb: 0, 0, 1
Rectangle:
pos: 0, 0 # <- shold be this
size: self.size
并且您不应该为 ScrollView
编写任何规则,因为它会影响可能存在于您的代码之外的所有实例。因此,改为定义一个子类并为其编写规则。
class MyScrollView(ScrollView):
pass
<MyScrollView>:
...
您必须缩放 ScatterLayout
的大小以使子项的位置保持一致。我还加入了
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.scatter import Scatter
from kivy.uix.scatterlayout import ScatterLayout
from kivy.uix.scrollview import ScrollView
kv = '''
#:kivy 1.11.1
<MyScatter>:
do_translation_y: False
do_rotation: False
do_scale: False
canvas:
Color:
hsv: .1, 1, .5
Rectangle:
size: 100, 100
<MyScrollView>:
size_hint: None, None
size: 640, 480
pos_hint: {'center_x': .5, 'center_y': .5}
scroll_type: ['bars']
bar_width: 10
bar_inactive_color: self.bar_color
canvas:
Color:
rgb: 1, 0, 0
Rectangle:
pos: self.pos
size: self.size
<MyScatterLayout>:
size_hint: None, None
size: 1280 * self.scale, 720 * self.scale # this is the correction
do_translation: False
do_rotation: False
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
canvas:
Color:
rgb: 0, 0, 1
Rectangle:
pos: 0, 0
size: self.size
'''
Builder.load_string(kv)
class MyScatter(Scatter):
pass
class MyScatterLayout(ScatterLayout):
pass
class MyScrollView(ScrollView):
pass
class MyApp(App):
def build(self):
layout = MyScatterLayout()
layout.add_widget(MyScatter())
root = MyScrollView()
root.add_widget(layout)
return root
if __name__ == '__main__':
MyApp().run()