2013-10-21 9 views
7

Ich würde gerne wissen, wie Bildschirme mit einem on_press-Ereignis zu einer Schaltfläche gebunden ändern, ohne Verwendung einer KV-Datei/KV-Sprache.Kivy: Ändern von Bildschirmen in Screen Manager mit einem on_press-Ereignis

Ich habe die Kivy-Dokumentation gelesen, konnte aber nur mit einer KV-Datei Lösungen finden.

Beispiel:

screenmanager.current = 'screen2'

Aber ich kann nicht herausfinden, wie man das gleiche erreichen über einen Button:

on_press: root.manager.current = 'screen2'

ich auch den Bildschirm in der Haupt Python-Datei ändern .

Antwort

6

Eine einfache Möglichkeit, dies zu erreichen, ist Ihre eigene Schaltfläche Unterklasse zu definieren:

class ScreenButton(Button): 
    screenmanager = ObjectProperty() 
    def on_press(self, *args): 
     super(ScreenButton, self).on_press(*args) 
     self.screenmanager.current = 'whatever' 

Die on_press Methode wird automatisch aufgerufen, wenn die Taste gedrückt wird, so dass die current Eigenschaft Screen wird geändert.

Dann können Sie Code so etwas wie haben:

sm = ScreenManager() 

sc1 = Screen(name='firstscreen') 
sc1.add_widget(ScreenButton(screenmanager=sm)) 

sc2 = Screen(name='whatever') 
sc2.add_widget(Label(text='another screen')) 

sm.add_widget(sc1) 
sm.add_widget(sc2) 

Durch Anklicken der Schaltfläche sollte die Bildschirme wechseln je nach Bedarf.

Ein anderer Weg (was wahrscheinlich ist, wie kv Sprache es tatsächlich tut) wäre manuell die bind Methode zu verwenden.

def switching_function(*args): 
    some_screen_manager.current = 'whatever' 

some_button.bind(on_press=switching_function) 

Dies würde bedeuten, dass switching_function aufgerufen wird, wenn some_button gedrückt wird. Natürlich gibt es hier eine Menge Flexibilität hinsichtlich der Art und Weise, wie und wann Sie die Funktion definieren, so dass Sie zum Beispiel etwas allgemeineres tun könnten, wie den Screenmanager als erstes Argument an die Funktion übergeben.

Ich habe diesen Code nicht getestet und es ist keine vollständige App, aber hoffentlich ist die Bedeutung klar. Beide Methoden sollten gut funktionieren. Sie können wählen, was am sinnvollsten ist. Ich könnte später ein vollständigeres Beispiel konstruieren.

+0

Vielen Dank für Ihre Antwort. Die Verwendung der Unterklassen-Lösung hat mir geholfen, das zu erreichen, was ich versuchte. Danke noch einmal. – Derick

2

Eine andere Lösung, die setter Methode der Eventdispatcher zu verwenden, war eine Referenz auf die Setter-Funktion zu erhalten für screen_manager.current

button.bind(on_press=partial(sm.setter('current'), (sm, 'whatever')) 

natürlich, es ist nicht sehr sexy, deshalb kv oft ein sauberer Lösung für diese Dinge, aber es sollte funktionieren.

ps: Wenn Sie nichts darüber wissen, kommt partial aus dem functools Modul, und es ist oft nützlich, diese Art von Rückrufen mit einem vorgeladenen Parameter zu erstellen.

+0

Ich bin ziemlich neu zu Kivy, also Sexiness ist nicht hoch auf meiner Liste. Das wird mir sehr nützlich sein. Vielen Dank. – Derick

5

Ein Arbeitsbeispiel mit zwei Bildschirmen, nicht alles kv-Datei in Python getan:

import kivy 
kivy.require('1.8.0') 

from kivy.app import App 
from kivy.uix.screenmanager import Screen, ScreenManager 
from kivy.uix.boxlayout import BoxLayout 
from kivy.uix.label import Label 
from kivy.uix.button import Button 
from kivy.properties import ObjectProperty 

class ScreenOne(Screen): 

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

     my_box1 = BoxLayout(orientation='vertical') 
     my_label1 = Label(text="BlaBlaBla on screen 1", font_size='24dp') 
     my_button1 = Button(text="Go to screen 2",size_hint_y=None, size_y=100) 
     my_button1.bind(on_press=self.changer) 
     my_box1.add_widget(my_label1) 
     my_box1.add_widget(my_button1) 
     self.add_widget(my_box1) 

    def changer(self,*args): 
     self.manager.current = 'screen2' 

class ScreenTwo(Screen): 

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

     my_box1 = BoxLayout(orientation='vertical') 
     my_label1 = Label(text="BlaBlaBla on screen 2",font_size='24dp') 
     my_button1 = Button(text="Go to screen 1",size_hint_y=None, size_y=100) 
     my_button1.bind(on_press=self.changer) 
     my_box1.add_widget(my_label1) 
     my_box1.add_widget(my_button1) 
     self.add_widget(my_box1) 

    def changer(self,*args): 
     self.manager.current = 'screen1' 

class TestApp(App): 

     def build(self): 
      my_screenmanager = ScreenManager() 
      screen1 = ScreenOne(name='screen1') 
      screen2 = ScreenTwo(name='screen2') 
      my_screenmanager.add_widget(screen1) 
      my_screenmanager.add_widget(screen2) 
      return my_screenmanager 

if __name__ == '__main__': 
    TestApp().run() 
+0

Gibt es einen besonderen Grund, dass dies nicht mit Kivy 1.9.2 funktioniert? –

Verwandte Themen