2013-03-26 42 views
2

我有这段代码。如果我增加了一定数量的手风琴项目,该应用程序就会失灵。 gridLayout版本(注释掉)按预期工作。犯罪区域位于HERE和THERE之间。Kivy ScrollView +手风琴错误

from kivy.app import App 
from kivy.uix.spinner import Spinner, SpinnerOption 
from kivy.uix.boxlayout import BoxLayout 
from kivy.uix.accordion import Accordion, AccordionItem 
from kivy.uix.label import Label 
from kivy.uix.button import Button 
from kivy.uix.scrollview import ScrollView 
from kivy.uix.gridlayout import GridLayout 
from kivy.core.window import Window 

class MusicController(App): 

    def build(self): 
     b = BoxLayout(orientation='vertical') 
     top = Spinner(text = '12', values = ["Songs","Artist","Playlist","Search"], background_color = (.3,.2,.5,1), size_hint_y = 0.1) 

    #<HERE># 

     items = Accordion(orientation='vertical') 
     for x in xrange(30): 
      item = AccordionItem(title='Title %d' % x) 
      buttons = BoxLayout() 
      buttons.add_widget(Button(text='Play')) 
      buttons.add_widget(Button(text='Pause')) 
      buttons.add_widget(Button(text='Pause')) 
      item.add_widget(buttons) 
      items.add_widget(item) 

     #~ items = GridLayout(cols=1, spacing=10, size_hint_y=None) 
     #~ items.bind(minimum_height=items.setter('height')) 
     #~ for i in range(30): 
      #~ btn = Button(text=str(i), 

    #<THERE># 

     sv = ScrollView(do_scroll_x = False) 
     sv.add_widget(items) 
     now_playing = BoxLayout(size_hint_y = 0.1) 
     for widget in ["Prev","Play","Pause","Next","NP"]: 
      now_playing.add_widget(Button(text=widget)) 

     b.add_widget(top) 
     b.add_widget(sv) 
     b.add_widget(now_playing) 
     return b 

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

回答

3

正如您控制台上的错误提示

[WARNING] [Accordion ] not enough space for displaying all children 
[WARNING] [Accordion ] need XXXX, got XXXXpx 
[WARNING] [Accordion ] layout aborted. 

只是增加给予手风琴的空间,因此它可以容纳所有它的孩子

更改代码的行19

items = Accordion(orientation='vertical', size_hint_y=None, height=50*30) 

应该工作。

在GridLayout中,通过将Gridlayout的minimum_height(通过组合儿童的高度计算)与其高度绑定,可以做到这一点。

items.bind(minimum_height=items.setter('height')) 

手风琴没有这种方便的方法,所以你必须自己动手。

为了让更多的动态,你可以绑定到手风琴的孩子财产,像这样:

item.bind(children=self.update_size) 

然后定义update_size像这样::

def update_size(self, instance, value): 
    # change 50 to what you want your AccordionItem height to be. 
    instance.size = 50*len(instance.children) 
+0

这工作,我很欣赏它。但为什么另一个容器不需要这个,有没有办法让它更具动态性?我的意思不是要忘恩负义,我很欣赏这一点。 – 2013-03-27 04:23:40

+1

更新了包含解释的答案,基本上你将GridLayout的高度绑定到minimum_height。 – 2013-03-27 13:45:20