2014-09-22 74 views
0

在我的應用程序中,我有多個屏幕。每個屏幕對應一個類。現在我想顯示在另一個屏幕上某個類(屏幕)中計算出的屬性。下面是一個簡單的例子來概述我的問題。在WordComprehension類中,每次按下按鈕時,NumericProperty count_r都會遞增。現在,我想在ScoreScreen中顯示此計算結果。感謝您的建議。 這裏是的.py:如何在kivy中將屬性從一個類傳遞到另一個類

import kivy 
from kivy.app import App 

from kivy.uix.boxlayout import BoxLayout 
from kivy.uix.floatlayout import FloatLayout 
from kivy.uix.label import Label 
from kivy.uix.button import Button 

from kivy.properties import ObjectProperty 
from kivy.properties import NumericProperty 


class AppScreen(FloatLayout): 
    app = ObjectProperty(None) 

class MainMenu(AppScreen): 
    pass 

class ScoreScreen(AppScreen): 

    score = NumericProperty(0) 
    def get_score(self): 
     wordcomp = WordComprehension() 
     self.score = wordcomp.count_r 


class WordComprehension(AppScreen): 
    count_r = NumericProperty(0) 
    count_w = NumericProperty(0) 

    def do_something(self): 
     self.count_r += 1 


class InterfaceApp(App): 
    def build(self): 
     self.screens = {} 
     self.screens["wordcomp"] = WordComprehension(app=self) 
     self.screens["menu"] = MainMenu(app=self) 
     self.screens["score"] = ScoreScreen(app=self) 
     self.root = FloatLayout() 
     self.goto_screen("menu") 
     return self.root 

    def goto_screen(self, screen_name): 
     self.root.clear_widgets() 
     self.root.add_widget(self.screens[screen_name]) 


if __name__ == "__main__": 
    InterfaceApp().run() 

和.kv:

#:kivy 1.8.0 

<MainMenu>: 
    BoxLayout: 
     orientation: 'vertical' 
     Label: 
      text: "Choose Category" 
      font_size: 30 
     Button: 
      text: 'Word Comprehension' 
      on_press: root.app.goto_screen("wordcomp") 
     Button: 
      text: 'Highscore' 
      on_press: root.app.goto_screen("score") 
      disabled: False 

<ScoreScreen>: 
    BoxLayout: 
     orientation: 'vertical' 
     Button: 
      text: 'get score' 
      on_press: root.get_score() 
     Label: 
      text: "Word Comprehension right answers:" + str(root.score) 
     Button: 
      text: 'Main Menu' 
      on_release: root.app.goto_screen("menu") 


<WordComprehension>: 
    BoxLayout: 
     orientation: 'vertical' 
     Label: 
      text: str(root.count_r) 
     Button: 
      text: 'Do something' 
      on_release: root.do_something() 
     Button: 
      text: 'Menu' 
      on_press: root.app.goto_screen("menu") 

回答

3

可以kivy特性相互結合,這樣,當一個變化如此做其他的。要做到這一點,你需要綁定到類的setter()函數。 (http://kivy.org/docs/api-kivy.event.html

以下是你需要做的:

1)創建的count_r在ScoreScreen一個NumericProperty。 2)綁定在WordComprehension的count_r NumericProperty到NumericProperty在ScoreScreen像這樣: '''in class WordComprehension ''' self.bind(count_r=self.score_screen.setter('count_r')

現在的伎倆是,你需要在你的WordComprehension類的ScoreScreen實例的引用。在我的例子中,我假設你在self.score_screen有一個參考。我會把它留給你,你想如何分配該參考。

現在每當count_r在WordComprehension中更改,setter函數(實質上是一個setattr())在ScoreScreen的'count_r'屬性上被調用。

另一件事:get_score()中的行wordcomp = WordComprehension()未引用所需的同一個WordComprehension實例。您正在創建WordComprehension類的新對象,並引用它的count_r,這將是它的默認值。

EDIT1不知道這是否是你想要的,但是這個代碼將會使每當count_r屬性更改比分屬性更新:

import kivy 
from kivy.app import App 

from kivy.uix.boxlayout import BoxLayout 
from kivy.uix.floatlayout import FloatLayout 
from kivy.uix.label import Label 
from kivy.uix.button import Button 

from kivy.properties import ObjectProperty 
from kivy.properties import NumericProperty 


class AppScreen(FloatLayout): 
    app = ObjectProperty(None) 

class MainMenu(AppScreen): 
    pass 

class ScoreScreen(AppScreen): 
    count_r = NumericProperty(0) 
    score = NumericProperty(0) 

    # This is making a new WordComprehension object, and thus will not have 
    # the correct value of score. We no longer need this is we are binding properties 
    # together. 
    #def get_score(self): 
    # wordcomp = WordComprehension() 
    # self.score = wordcomp.count_r 


class WordComprehension(AppScreen): 
    count_r = NumericProperty(0) 
    count_w = NumericProperty(0) 

    def do_something(self): 
     self.count_r += 1 


class InterfaceApp(App): 
    def build(self): 
     self.screens = {} 
     self.screens["wordcomp"] = WordComprehension(app=self) 
     self.screens["menu"] = MainMenu(app=self) 
     self.screens["score"] = ScoreScreen(app=self) 
     self.root = FloatLayout() 
     self.goto_screen("menu") 

     # Bind the two properties together. Whenever count_r changes in the wordcomp 
     # screen, the score property in the score screen will reflect those changes. 
     self.screens["wordcomp"].bind(count_r=self.screens["score"].setter('score')) 

     return self.root 

    def goto_screen(self, screen_name): 
     self.root.clear_widgets() 
     self.root.add_widget(self.screens[screen_name]) 


if __name__ == "__main__": 
    InterfaceApp().run() 
+0

非常感謝您的回覆。儘管如此,我還是不太確定如何將您的改進集成到代碼中。對不起,我對Python和Kivy絕對陌生。你可能會發佈一個完整的代碼,包括你的改變? – Lorenz 2014-09-22 16:09:59

+0

這正是我想要的。非常感謝你的幫助! – Lorenz 2014-09-22 20:17:39

相關問題