2017-04-03 41 views
0

我想创建一个滚动视图,我通过下拉菜单选择一个选项,然后按+按钮将一行中的两个标签添加到滚动视图。这是我的代码到目前为止:Kivy - 创建一个可缩放的滚动视图

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() 

在scrollview中的白色食物和卡路里标签是例子。理想情况下,他们将浮动到顶部,然后我可以从下拉列表中选择一个新选项,并将更多内容添加到队列中。我将如何去做这件事?目前,如果我添加了很多在scrollview中堆叠的标签,则不会启用滚动。

回答

1

要创建一个项目,以适应两列,foodcalories这将是可能是最好的,从表格的标题,即FoodCalories并为他们创建一个单独的容器作为FoodItem,这就是“复制”行为只是一个BoxLayout

FoodItem将有两个StringProperties

  • 食品
  • 卡路里

,您可以通过root.foodroot.calories访问这些千伏。

现在要直接在kv中创建这样的项目并将其放入ScrollView,您需要Factory,因此默认情况下不可用,因此需要导入。与你基本上可以这样做:

Factory.MyWidget() 

,它会创建窗口小部件,你需要传递给你的GridLayoutadd_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('') 

... 

还要考虑使用的纯DropdownSpinner,而不是因为它使事情变得更容易(你会避免on_parent行为)。