2016-05-12 18 views
0

Hintergrund: Ich verwende ausschließlich Python, um die Kivy-Bildschirme zu implementieren. Ich habe zwei Bildschirme, die beide eine Liste und zwei Schaltflächenreihen enthalten. Ich dachte, es wäre eine gute Programmierpraxis, eine Bildschirmklasse mit diesen Layouts zu erstellen und anschließend Vererbung zu verwenden, um die zwei Bildschirme zu erstellen und den Layouts bei Bedarf Schaltflächen hinzuzufügen.Python Kivy Screen Inheritance

Das Problem: Wenn ich dies tue, finde ich jedoch, dass ich in den Kinderbildschirmen nicht auf self.manager.current < zugreifen kann - speziell '.current' Es hat auch keinen Zugriff auf self.manager.transition. Ich möchte verstehen, warum das passiert und wie/welche Dinge hier vererbt werden.

Frage: Weiß jemand, warum oder wie er nicht die Eigenschaften des übergeordneten Bildschirms Manager erbt?

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

Antwort

0

Nun, ich sehe ScreenManager nicht das ist im Grunde das, was Sie mit self.manager (Objekt) erhalten, so ...

Keine ScreenManager mit Screens hinzugefügt entweder in Python oder kv wie Widgets (add_widget()) , nein self.manager in einem der Screens - Sie können nicht auf etwas zugreifen, das nicht da ist.

Fügen Sie eine Klasse, die eine Wurzel für Ihre Bildschirme sein wird und machen Sie es ScreenManager + Bildschirme als Kinder hinzufügen.

Edit: Ich war wahrscheinlich blind, aber ich habe nicht on_press=.. Sachen. Es gibt das Problem, weil Sie die Funktion nicht einem Ereignis zugewiesen haben, sondern genannt die Funktion richtig, wenn Sie ('search') am Ende setzen. (Versuchen Sie, self.parent

Kivy Ereignisse (mindestens "on_") fangen die Funktion, aber nicht die Parameter, nicht direkt. Deshalb sollten Sie partial

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

dies mit dem Fehler weg ist, aber einige Adapter Bindung springt verwenden müssen, was ich habe wirklich keine Ahnung, wie sie zu beheben, wie ich es nicht, dass viel.

+0

Entsetzlich leid, ich habe diese Klasse, ich habe die Frage bearbeitet, um die Klasse aufzunehmen. Es hat immer noch das gleiche Problem wie in der Frage angegeben. – jdanaher

+0

@jdanaher Ich habe die Antwort bearbeitet – KeyWeeUsr

+0

Danke! Ich werde einige Zeit damit verbringen, damit herumzuspielen. Ich war auch in der Lage, das Problem teilweise zu beheben, indem ich manager = sm in die Parameter für die Bildschirme setzte, als ich sie mit add_widget() zu sm hinzufügte. Denkst du, es wäre besser, die Bildschirme in der Manager-Klasse nur als zwei Kopien von ListScreen() mit unterschiedlichen Namen zu erstellen und dann einfach die Schaltflächen dort hinzuzufügen? – jdanaher