Kivy - 创建一个可扩展的 ScrollView
Kivy - creating a scalable ScrollView
我正在尝试创建一个滚动视图,其中我通过下拉菜单 select 一个选项,然后按 + 按钮将两个标签连续添加到滚动视图。到目前为止,这是我的代码:
from kivy.app import App
from kivy.uix.label import Label
from kivy.lang import Builder
from kivy.properties import ListProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
class CaloriesScreen(Screen):
pass
class theScreenManager(ScreenManager):
pass
root_widget = Builder.load_string('''
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
theScreenManager:
CaloriesScreen:
<CaloriesScreen>:
name: 'calories'
BoxLayout:
orientation: 'vertical'
BoxLayout:
orientation: 'horizontal'
size_hint: 1, .3
Button:
text: '<'
size_hint: .1, 1
font_size: 75
background_normal: ""
background_color: 0.18, .5, .92, 1
on_release: app.root.current = 'main'
Label:
text: 'Calories'
halign: 'left'
font_size: 50
canvas.before:
Color:
rgb: 0.18, .5, .92
Rectangle:
pos: self.pos
size: self.size
Widget:
size_hint: .1, 1
canvas.before:
Color:
rgb: 0.18, .5, .92
Rectangle:
pos: self.pos
size: self.size
BoxLayout:
orientation: 'horizontal'
size_hint: 1, .4
spacing: 50
canvas.before:
Color:
rgb: 0.8, 0.8, 0.8
Rectangle:
pos: self.pos
size: self.size
Label:
text: 'Recipes'
font_size: 30
color: 0.18, .5, .92, 1
Button:
id: btn
text: 'Select a recipe...'
font_size: 30
on_release: dropdown.open(self)
height: '48dp'
pos_hint: { 'top' : 0.75}
size_hint: .8, .5
DropDown:
id: dropdown
on_parent: self.dismiss()
on_select: btn.text = '{}'.format(args[1])
Button:
text: 'Simple Cheese Omelette'
size_hint_y: None
height: '48dp'
on_release: dropdown.select('First Item')
Button:
text: 'Burger'
size_hint_y: None
height: '48dp'
on_release: dropdown.select('Second Item')
Button:
text: 'Tomato and Caper Linguine'
size_hint_y: None
height: '48dp'
on_release: dropdown.select('Third Item')
Button:
text: '+'
font_size: 30
background_normal: ""
background_color: 0.18, .5, .92, 1
pos_hint: { 'top' : 0.65}
size_hint: .1, .3
#on_release:
Widget:
size_hint: .02, 1
BoxLayout:
orientation: 'horizontal'
size_hint: 1, .2
canvas.before:
Color:
rgb: 0.18, .5, .92
Rectangle:
pos: self.pos
size: self.size
Label:
text:'Food'
color: (1, 1, 1, 1)
Label:
text:'Calories'
color: (1, 1, 1, 1)
ScrollView:
scroll_timeout: 250
scroll_distance: 20
do_scroll_y: True
do_scroll_x: False
GridLayout:
id: grid
cols: 2
spacing: 10
padding: 10
Label:
text:'Food'
color: (1, 1, 1, 1)
Label:
text:'Calories'
color: (1, 1, 1, 1)
''')
class temprecipeapp(App):
def build(self):
return root_widget
if __name__ == "__main__":
temprecipeapp().run()
滚动视图上白色的食物和卡路里标签就是示例。理想情况下,它们会浮到顶部,然后我就可以 select 从下拉列表中选择一个新选项并将更多选项添加到队列中。我该怎么做?目前,如果我添加大量堆叠在滚动视图中的标签,则滚动不会启用。
要创建适合两列的项目,food
和 calories
可能最好 "copy" table [=54] 的行为=] 即 Food
和 Calories
并为它们创建一个单独的容器作为 FoodItem
,这只是一个 BoxLayout
.
那个FoodItem
会有两个StringProperties
:
- 食物
- 卡路里
您可以通过 root.food
、root.calories
.
在 kv 中访问它们
现在要直接在 kv 中创建这样的项目并将其放入 ScrollView
,您需要 Factory
,默认情况下不可用,因此请导入。有了它,你基本上可以做到这一点:
Factory.MyWidget()
它会创建一个小部件实例,您需要将其传递给 GridLayout
的 add_widget
方法。
代码编辑:
...
from kivy.properties import StringProperty
...
root_widget = Builder.load_string('''
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
#:import Factory kivy.factory.Factory # <- import Factory
...
DropDown:
id: dropdown
# on_parent: self.dismiss() <- don't do this
on_select: btn.text = '{}'.format(args[1])
Button:
text: 'Simple Cheese Omelette'
size_hint_y: None
height: '48dp'
on_release: dropdown.select('First Item')
Button:
text: 'Burger'
size_hint_y: None
height: '48dp'
on_release: dropdown.select('Second Item')
Button:
text: 'Tomato and Caper Linguine'
size_hint_y: None
height: '48dp'
on_release: dropdown.select('Third Item')
Button:
text: '+'
font_size: 30
background_normal: ""
background_color: 0.18, .5, .92, 1
pos_hint: { 'top' : 0.65}
size_hint: .1, .3
on_release: grid.add_widget(Factory.FoodItem(food=btn.text, calories='10')) <- add a new item
...
ScrollView:
scroll_timeout: 250
scroll_distance: 20
do_scroll_y: True
do_scroll_x: False
GridLayout:
id: grid
cols: 1 <- change cols
size_hint_y: None
height: self.minimum_height <- make the layout resize itself
spacing: 10
padding: 10
<FoodItem>:
size_hint_y: None
height: 20 <- set a size for the item
Label:
text: root.food
color: (1, 1, 1, 1)
Label:
text: root.calories
color: (1, 1, 1, 1)
''')
class FoodItem(BoxLayout):
food = StringProperty('')
calories = StringProperty('')
...
还可以考虑使用 Spinner
而不是纯 Dropdown
,因为它使事情变得更容易(并且您将避免 on_parent
行为)。
我正在尝试创建一个滚动视图,其中我通过下拉菜单 select 一个选项,然后按 + 按钮将两个标签连续添加到滚动视图。到目前为止,这是我的代码:
from kivy.app import App
from kivy.uix.label import Label
from kivy.lang import Builder
from kivy.properties import ListProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
class CaloriesScreen(Screen):
pass
class theScreenManager(ScreenManager):
pass
root_widget = Builder.load_string('''
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
theScreenManager:
CaloriesScreen:
<CaloriesScreen>:
name: 'calories'
BoxLayout:
orientation: 'vertical'
BoxLayout:
orientation: 'horizontal'
size_hint: 1, .3
Button:
text: '<'
size_hint: .1, 1
font_size: 75
background_normal: ""
background_color: 0.18, .5, .92, 1
on_release: app.root.current = 'main'
Label:
text: 'Calories'
halign: 'left'
font_size: 50
canvas.before:
Color:
rgb: 0.18, .5, .92
Rectangle:
pos: self.pos
size: self.size
Widget:
size_hint: .1, 1
canvas.before:
Color:
rgb: 0.18, .5, .92
Rectangle:
pos: self.pos
size: self.size
BoxLayout:
orientation: 'horizontal'
size_hint: 1, .4
spacing: 50
canvas.before:
Color:
rgb: 0.8, 0.8, 0.8
Rectangle:
pos: self.pos
size: self.size
Label:
text: 'Recipes'
font_size: 30
color: 0.18, .5, .92, 1
Button:
id: btn
text: 'Select a recipe...'
font_size: 30
on_release: dropdown.open(self)
height: '48dp'
pos_hint: { 'top' : 0.75}
size_hint: .8, .5
DropDown:
id: dropdown
on_parent: self.dismiss()
on_select: btn.text = '{}'.format(args[1])
Button:
text: 'Simple Cheese Omelette'
size_hint_y: None
height: '48dp'
on_release: dropdown.select('First Item')
Button:
text: 'Burger'
size_hint_y: None
height: '48dp'
on_release: dropdown.select('Second Item')
Button:
text: 'Tomato and Caper Linguine'
size_hint_y: None
height: '48dp'
on_release: dropdown.select('Third Item')
Button:
text: '+'
font_size: 30
background_normal: ""
background_color: 0.18, .5, .92, 1
pos_hint: { 'top' : 0.65}
size_hint: .1, .3
#on_release:
Widget:
size_hint: .02, 1
BoxLayout:
orientation: 'horizontal'
size_hint: 1, .2
canvas.before:
Color:
rgb: 0.18, .5, .92
Rectangle:
pos: self.pos
size: self.size
Label:
text:'Food'
color: (1, 1, 1, 1)
Label:
text:'Calories'
color: (1, 1, 1, 1)
ScrollView:
scroll_timeout: 250
scroll_distance: 20
do_scroll_y: True
do_scroll_x: False
GridLayout:
id: grid
cols: 2
spacing: 10
padding: 10
Label:
text:'Food'
color: (1, 1, 1, 1)
Label:
text:'Calories'
color: (1, 1, 1, 1)
''')
class temprecipeapp(App):
def build(self):
return root_widget
if __name__ == "__main__":
temprecipeapp().run()
滚动视图上白色的食物和卡路里标签就是示例。理想情况下,它们会浮到顶部,然后我就可以 select 从下拉列表中选择一个新选项并将更多选项添加到队列中。我该怎么做?目前,如果我添加大量堆叠在滚动视图中的标签,则滚动不会启用。
要创建适合两列的项目,food
和 calories
可能最好 "copy" table [=54] 的行为=] 即 Food
和 Calories
并为它们创建一个单独的容器作为 FoodItem
,这只是一个 BoxLayout
.
那个FoodItem
会有两个StringProperties
:
- 食物
- 卡路里
您可以通过 root.food
、root.calories
.
现在要直接在 kv 中创建这样的项目并将其放入 ScrollView
,您需要 Factory
,默认情况下不可用,因此请导入。有了它,你基本上可以做到这一点:
Factory.MyWidget()
它会创建一个小部件实例,您需要将其传递给 GridLayout
的 add_widget
方法。
代码编辑:
...
from kivy.properties import StringProperty
...
root_widget = Builder.load_string('''
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
#:import Factory kivy.factory.Factory # <- import Factory
...
DropDown:
id: dropdown
# on_parent: self.dismiss() <- don't do this
on_select: btn.text = '{}'.format(args[1])
Button:
text: 'Simple Cheese Omelette'
size_hint_y: None
height: '48dp'
on_release: dropdown.select('First Item')
Button:
text: 'Burger'
size_hint_y: None
height: '48dp'
on_release: dropdown.select('Second Item')
Button:
text: 'Tomato and Caper Linguine'
size_hint_y: None
height: '48dp'
on_release: dropdown.select('Third Item')
Button:
text: '+'
font_size: 30
background_normal: ""
background_color: 0.18, .5, .92, 1
pos_hint: { 'top' : 0.65}
size_hint: .1, .3
on_release: grid.add_widget(Factory.FoodItem(food=btn.text, calories='10')) <- add a new item
...
ScrollView:
scroll_timeout: 250
scroll_distance: 20
do_scroll_y: True
do_scroll_x: False
GridLayout:
id: grid
cols: 1 <- change cols
size_hint_y: None
height: self.minimum_height <- make the layout resize itself
spacing: 10
padding: 10
<FoodItem>:
size_hint_y: None
height: 20 <- set a size for the item
Label:
text: root.food
color: (1, 1, 1, 1)
Label:
text: root.calories
color: (1, 1, 1, 1)
''')
class FoodItem(BoxLayout):
food = StringProperty('')
calories = StringProperty('')
...
还可以考虑使用 Spinner
而不是纯 Dropdown
,因为它使事情变得更容易(并且您将避免 on_parent
行为)。