如何在kivy中将属性从一个类传递到另一个类

2024-10-01 13:24:32 发布

您现在位置:Python中文网/ 问答频道 /正文

在我的应用程序中,我有多个屏幕。每个屏幕对应一个类。现在我想在另一个屏幕上显示在某个类(屏幕)中计算的属性。下面是一个简单的例子来概括我的问题。在WordComprehension类中,每次按下按钮,NumericProperty计数都会递增。现在,我想在记分屏上显示这个计算的结果。谢谢你的建议。 这是.py:

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:

^{pr2}$

Tags: fromimportselfapp屏幕defcountclass
1条回答
网友
1楼 · 发布于 2024-10-01 13:24:32

您可以将kivy属性绑定到另一个属性,这样当一个属性发生变化时,另一个属性也会发生变化。为此,可以绑定到类的setter()函数。(http://kivy.org/docs/api-kivy.event.html

以下是您需要做的:

1)在ScoreScreen中为计数创建一个NumericProperty。 2) 将WordComprehension中的count\r NumericProperty绑定到ScoreScreen中的NumericProperty,如下所示: '''in class WordComprehension ''' self.bind(count_r=self.score_screen.setter('count_r')

现在的诀窍是,您需要在WordComprehension类中引用ScoreScreen实例。在我的示例中,假设您在self.score_screen中有一个对它的引用。我将由你来决定你想如何分配推荐人。在

现在,每当在WordComprehension中更改count\r时,就会对ScoreScreen的“count\r”属性调用setter函数(本质上是setattr())。在

另一件事:get_score()中的wordcomp = WordComprehension()行引用的不是您想要的同一个WordComprehension实例。您正在创建一个新的WordComprehension类对象,并引用它的count\r,这将是它的默认值。在

EDIT1不确定这是否是您想要的,但是每当count\r属性更改时,此代码将使score属性更新:

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()

相关问题 更多 >