2013-10-21 81 views
7

我想知道如何使用綁定到按鈕的on_press事件來切換屏幕,而無需使用KV文件/ KV語言。Kivy:使用on_press事件更改屏幕管理器中的屏幕

我已閱讀Kivy文檔,但只能使用KV文件找到解決方案。

例子:

screenmanager.current = 'screen2'

但我無法弄清楚如何使用按鈕來實現相同的:

on_press: root.manager.current = 'screen2'

我也可以用更改屏幕在主Python文件。

回答

6

一個簡單的方法來完成,這是定義你自己的按鈕子類:

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

按下按鈕時,on_press方法是自動調用,所以在屏幕顯示器的current屬性將被改變。

然後你就可以有代碼是這樣的:

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) 

點擊按鈕,需要應切換屏幕。

另一種方式(這可能是kv語言實際上是如何做到的)將手動使用bind方法。

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

some_button.bind(on_press=switching_function) 

這意味着,只要按下some_buttonswitching_function被調用。當然這裏有很多靈活性,關於如何以及何時定義函數,所以(比如)你可以做一些更一般的事情,比如將screenmanager作爲函數的第一個參數。

我沒有測試這個代碼,它不是一個完整的應用程序,但希望其含義很明確。這兩種方法都應該正常工作,你可以選擇最明智的方式。稍後我可能會構建一個更完整的示例。

+0

謝謝您的回答。使用子類解決方案幫助我實現了我正在嘗試做的事情。再次感謝。 – Derick

2

另一種解決方案,是使用此事件的setter方法,以獲取screen_manager.current

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

給setter函數的引用,它不是很性感,這就是爲什麼KV往往是一種更清潔解決這些事情,但它應該工作。

ps:如果您不知道它,partial來自functools模塊,並且通過預加載參數構建這些類型的回調通常很有用。

+0

我對kivy相當陌生,所以我的名單上性感不高。這對我來說非常方便。謝謝。 – Derick

5

有兩個屏幕,沒有KV文件都在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

有沒有特別的原因,這不適用於Kivy 1.9.2? –