2017-06-30 1 views
2

So habe ich ein Problem mit dem Bildschirmmanager zu verwenden. Da ich nun meine Screen-Klassen anlegen muss, um (Screen) anstelle von (GridLayout) überhaupt den Screenmanager zu verwenden, kann die Button/Layout-Verwaltung in Python nicht mehr kontrolliert werden? Es wurde verwendet, um 5 Spalten und 3 Zeilen für insgesamt 15 Tasten auf dem Bildschirm zu legen. Jetzt zeigt es nur ein großes mit (Screen) anstelle von Rasterlayout.Problem bei der Verwendung von ScreeManager mit Kivy - Tasten Layout funktioniert nicht mehr

class LandingScreen(Screen): 
def build(self): 
    return presentation 
def __init__(self, **kwargs): 
    super(LandingScreen, self).__init__(**kwargs) 
    self.cols = 5 
    self.buttons = [] # add references to all buttons here 

    # Loop to make 20 different buttons on screen 
    for x in range(15): 
     self.buttons.append(Button(text='button ' + str(x))) # make a reference to the button before adding it in 
     self.add_widget(self.buttons[x]) 
     self.buttons[x].background_normal = 'YOUTUBE.png' 

, wo die Tasten und Spalte Setup hier verwendet 3 Reihen von 5 Tasten mit dieser Schleife zu erstellen, ist es nicht, da ich (Screen) auf die Klasse statt (Gridlayout) zugegeben. Ich würde lieber nicht alle Schaltflächen in der .kv-Datei erstellen, da ich denke, dass es einfacher ist, in der .py zu verwalten und macht mehr Sinn für mich.

Hier ist meine .kv Datei:

<GridLayout>: 
    cols: 5 
    height: 480 
    width: 800 
    spacing: 25, 20 
    padding: 25,25 

<MyScreenManager>: 
    LandingScreen: 
    InputScreen: 

<InputScreen>: 
    AnchorLayout: 

<LandingScreen>: 
    GridLayout: 
     cols: 5 
     height: 480 
     width: 800 
     spacing: 25, 20 
     padding: 25,25 

Es ist offensichtlich überflüssig, weil ich versuche, herauszufinden, wie alle 15 Tasten wieder zeigen zu machen, nicht nur die eine.

Danke!

Antwort

1

Sie möchten die Tasten zu GridLayout innerhalb Screen, nicht zu Screen direkt hinzufügen. Verwenden Sie dazu eine id, um auf die GridLayout zu verweisen.

Sie können jedoch keine IDs in der Methode __init__ verwenden, da die in der kv-Datei definierten Regeln erst angewendet werden, wenn das entsprechende Widget vollständig initialisiert wurde. Die Lösung wird von Ryan Pi in dieser Frage richtig gesetzt:

Why can't I access the Screen.ids?

Auf der anderen Seite, Bildschirm zu ändern, später müssen Sie Namen Eigenschaft in Ihnen Bildschirme definieren.

sollte Ihr Code sein:

from kivy.app import App 
from kivy.lang import Builder 
from kivy.uix.screenmanager import ScreenManager, Screen 
from kivy.uix.button import Button 
from kivy.clock import Clock 


kv_text='''\ 

<MyScreenManager>: 
    LandingScreen: 
    InputScreen: 

<[email protected]>: 
    name: 'input_sc' 
    AnchorLayout: 
     id: anchor_1 

<[email protected]>: 
    name: 'landing_sc' 
    GridLayout: 
     id: grid_1 
     cols: 5 
     height: 480 
     width: 800 
     spacing: 25, 20 
     padding: 25,25 
''' 

class MyScreenManager(ScreenManager): 
    pass 


class LandingScreen(Screen): 
    def __init__(self, **kwargs): 
     super(LandingScreen, self).__init__(**kwargs) 
     self.buttons = [] # add references to all buttons here 
     Clock.schedule_once(self._finish_init) 

    def _finish_init(self, dt): 
     self.ids.grid_1.cols = 5 

     # Loop to make 20 different buttons on screen 
     for x in range(15): 
      self.buttons.append(Button(text='button {}'.format(x))) 
      self.ids.grid_1.add_widget(self.buttons[x]) 
      self.buttons[x].background_normal = 'YOUTUBE.png' 

class MyKivyApp(App): 
    def build(self): 
     return MyScreenManager() 

def main(): 
    Builder.load_string(kv_text) 
    app = MyKivyApp() 
    app.run() 

if __name__ == '__main__': 
    main() 

Wenn Sie Properties anstelle des ids-Methode (siehe documentation) verwenden möchten, sollten Sie so etwas tun:

from kivy.app import App 
from kivy.lang import Builder 
from kivy.uix.screenmanager import ScreenManager, Screen 
from kivy.uix.button import Button 
from kivy.clock import Clock 
from kivy.properties import ObjectProperty 


kv_text='''\ 

<MyScreenManager>: 
    LandingScreen: 
    InputScreen: 

<[email protected]>: 
    name: 'input_sc' 
    AnchorLayout: 
     id: anchor_1 

<[email protected]>: 
    name: 'landing_sc' 
    grid_1: grid_1 
    GridLayout: 
     id: grid_1 
     cols: 5 
     height: 480 
     width: 800 
     spacing: 25, 20 
     padding: 25,25 
''' 

class MyScreenManager(ScreenManager): 
    pass 


class LandingScreen(Screen): 

    grid_1 = ObjectProperty(None) #<<<< Propertie 

    def __init__(self, **kwargs): 
     super(LandingScreen, self).__init__(**kwargs) 
     self.buttons = [] # add references to all buttons here 
     Clock.schedule_once(self._finish_init) 

    def _finish_init(self, dt): 
     self.grid_1.cols = 5 
     # Loop to make 20 different buttons on screen 
     for x in range(15): 
      self.buttons.append(Button(text='button{}'.format(x))) 
      self.grid_1.add_widget(self.buttons[x]) 
      self.buttons[x].background_normal = 'star.png' 

class MyKivyApp(App): 
    def build(self): 
     return MyScreenManager() 

def main(): 
    Builder.load_string(kv_text) 
    app = MyKivyApp() 
    app.run() 

if __name__ == '__main__': 
    main() 
+0

Super, danke für die Antwort . Soweit der self.ids.grid_1.cols Teil geht - kann also prinzipiell jede kivy Funktionalität in der .py Datei auf diese Weise bearbeitet werden? – John

+1

@Austin, Ids können Sie auf jedes Widget verweisen und seine Methoden/Attribute in Python verwenden. Siehe https://kivy.org/docs/guide/lang.html#accessing-widgets-defined-inside-kv-lang-in-your-python-code – FJSevilla

+0

Vielen Dank, das war ein grundlegender Teil von Kivy Ich habe nicht gegriffen. Das macht die Dinge jetzt in vielerlei Hinsicht einfacher. – John

Verwandte Themen