2013-10-21 13 views
7

Vorrei sapere come modificare gli schermi utilizzando un evento on_press associato a un pulsante, senza utilizzare un file KV/linguaggio KV.Kivy: modifica delle schermate in screen manager con un evento on_press

Ho letto la documentazione di Kivy, ma sono stato solo in grado di trovare soluzioni utilizzando un file KV.

Esempio:

on_press: root.manager.current = 'screen2'

Posso anche cambiare lo schermo nel file python principale utilizzando:

screenmanager.current = 'screen2'

Ma Non riesco a capire come ottenere lo stesso utilizzando un pulsante .

risposta

6

Un modo semplice per ottenere questo risultato è quello di definire il pulsante propria sottoclasse:

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

Il metodo on_press viene chiamato automaticamente quando si preme il pulsante, quindi la proprietà del ScreenManager current sarà cambiato.

Quindi è possibile avere il codice qualcosa di simile:

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) 

Facendo clic sul pulsante dovrebbe cambiare le schermate, come richiesto.

Un altro modo (che è probabilmente il modo in cui il linguaggio kv lo esegue) sarebbe quello di utilizzare manualmente il metodo bind.

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

some_button.bind(on_press=switching_function) 

Ciò significherebbe che switching_function viene chiamata ogni volta che viene premuto some_button. Naturalmente qui c'è molta flessibilità riguardo a come e quando si definisce la funzione, quindi (per esempio) si potrebbe fare qualcosa di più generale come passare lo screenmanager come primo argomento della funzione.

Non ho testato questo codice e non è un'app completa, ma si spera che il significato sia chiaro. Entrambi i metodi dovrebbero funzionare bene, è possibile scegliere il modo che sembra più ragionevole. Potrei costruire un esempio più completo più tardi.

+0

Grazie per la risposta. L'utilizzo della soluzione di sottoclasse mi ha aiutato a ottenere ciò che stavo cercando di fare. Grazie ancora. – Derick

2

Un'altra soluzione, è stato quello di utilizzare il metodo di EventDispatcher setter, per ottenere un riferimento alla funzione setter per screen_manager.current

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

, naturalmente, non è molto sexy, è per questo che kv è spesso un pulitore soluzione a queste cose, ma dovrebbe funzionare.

ps: nel caso in cui non si sa a questo proposito, partial proviene dal modulo functools, ed è spesso utile per costruire questo tipo di callback con un parametro precaricato.

+0

Sono abbastanza nuovo per Kivy, quindi la sensualità non è in cima alla mia lista. Questo sarà molto utile per me. Grazie. – Derick

5

Un esempio di lavoro con due schermi, nessun file kv tutto fatto in Python:

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

C'è una ragione particolare per cui questo non funzionerà con Kivy 1.9.2? –

Problemi correlati