2016-05-12 74 views
0

背景:我僅使用Python來實現Kivy屏幕。我有兩個屏幕,都包含一個列表和兩行按鈕。我認爲創建一個具有這些佈局的屏幕類是一種很好的編程習慣,然後使用繼承來創建兩個屏幕並根據需要向佈局添加按鈕。Python Kivy屏幕繼承

問題:但是,當我這樣做時,我發現在子屏幕中,我無法訪問self.manager.current < - 特別是'.current'它也無法訪問self.manager.transition。我希望理解爲什麼會發生這種情況,以及這裏如何/繼承什麼東西。

問題:有人知道爲什麼或者它如何不繼承父屏幕管理器的屬性?

from kivy.app import App 
from kivy.lang import Builder 
from kivy.uix.floatlayout import FloatLayout 
from kivy.uix.boxlayout import BoxLayout 
from kivy.uix.listview import ListView, ListItemButton 
from kivy.adapters import listadapter 
from kivy.uix.button import Button 
from kivy.properties import ListProperty, StringProperty 
from kivy.uix.screenmanager import ScreenManager, Screen, SlideTransition 


class ListScreen(Screen): # This is the super class that I am trying to inherit through 
    itemList = ListProperty([]) 
    selected_value = StringProperty() 
    layout = BoxLayout(orientation ='vertical') 
    top_buttons=BoxLayout(size_hint_y=0.1) 
    scrollable_list=ListView(adapter=listadapter, size_hint_y=0.8) 
    scrollable_list.data=itemList 
    scrollable_list.selection_mode='single' 
    scrollable_list.allow_empty_selection=False 
    # scrollable_list.cls=ListItemButton <-- Unrelated bug here, ignore this line 
    bot_buttons=BoxLayout(size_hint_y=0.1) 

    def __init__(self, **kwargs): 
     super(ListScreen, self).__init__(**kwargs) 

    def finalize_widgets(self): 
     self.layout.add_widget(self.top_buttons) 
     self.layout.add_widget(self.scrollable_list) 
     self.layout.add_widget(self.bot_buttons) 
     self.add_widget(self.layout) 

    def change(self,change): 
     self.selected_value = 'Selected: {}'.format(change.text) 

    def change_screen(self, screen_name): 
     self.manager.current = screen_name # <-- Here is the problem 


class SubScreen(ListScreen): 
# This is one of the child classes, intended to inherit Screen through the parent ListScreen class. 

    def __init__(self, **kwargs): 
     super(SubScreen, self).__init__(**kwargs) 

     save = Button(text='Save') 
     load = Button(text='Load') 
     new_d = Button(text='New') 
     new_s = Button(text='New Search') 

     self.top_buttons.add_widget(save) 
     self.top_buttons.add_widget(load) 
     self.top_buttons.add_widget(new_d) 
     self.top_buttons.add_widget(new_s) 

     new_s.bind(on_press = self.change_screen('search')) 


class ListBuilderApp(App): 
    def build(self): 
     sm = ScreenManager(transition=SlideTransition()) 
     sm.add_widget(SubScreen(name='list')) 
     sm.add_widget(SearchResults(name='results')) 
     sm.add_widget(SearchScreen(name='search')) 
     return sm 

if __name__ == "__main__": 
    ListBuilderApp().run() 

回答

0

好了,我沒有看到ScreenManager這基本上是你self.manager(對象)得到什麼,所以......

沒有ScreenManager與屏幕添加無論是在Python或KV類似部件(add_widget()) ,否self.managerScreens之內 - 你不能訪問那些不在那裏的東西。

添加一些類將作爲您的屏幕的根,並使其作爲ScreenManager +添加屏幕作爲兒童。

編輯: 我可能是盲人,但我沒有看到on_press=..的東西。有問題,因爲您沒有將該功能分配給某個事件,而是將稱爲功能正確,當您在末尾放置('search')時。 (嘗試做self.parent,你會看到)

Kivy事件(至少「on_」)捕捉函數,但不是參數,不直接。這就是爲什麼你需要使用partial

from functools import partial 
new_s.bind(on_press = partial(self.change_screen,'search')) 

有了這個錯誤了,但一些適配器綁定跳了出來,我真的沒有線索如何解決,因爲我不使用它那麼多。

+0

非常抱歉,我確實有過這樣的課,我已經編輯了包括課程的問題。它仍然存在與問題中所述相同的問題。 – jdanaher

+0

@jdanaher我編輯了答案 – KeyWeeUsr

+0

謝謝!我會花一些時間來解決這個問題。我還能夠通過將manager = sm放入屏幕的參數中來解決問題,因爲我使用add_widget()將它們添加到了sm中。你認爲將管理器類中的屏幕作爲兩個具有不同名稱的ListScreen()的副本,然後在那裏添加按鈕會更好嗎? – jdanaher