如何使用.py中的属性更新.kv中的标签文本? [英] How to update label text in .kv using properties in .py?

查看:42
本文介绍了如何使用.py中的属性更新.kv中的标签文本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 .kv 中的按钮并基于我类中的属性 nick 更新我的类 MainHero 中的值标签在 .kv 中.我需要自动处理此问题,因为还会自动生成许多其他属性,因此需要更新标签.这是我的代码的一部分:

I want to update values in my class MainHero using button in .kv and based on attribute nick in my class I need to update label in .kv. I need to handle this automatically, because many other attributes will be generated automatically so labels need to be updated. Here is part of my code:

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import *
from kivy.lang import Builder
from kivy.clock import Clock


class MainHero():
     def __init__(self):
          self.nick = "Player"

class FightScreen(Screen):
    def __init__(self, **kwargs):
        super(FightScreen, self).__init__(**kwargs)
        self.af_init = Clock.create_trigger(self._init)
        self.af_init()

    def _init(self, dt):
         self.app = App.get_running_app()
    
    def rename(self):
        self.app.main_hero.nick = "Renamed"


class ScreenManagement(ScreenManager):
    pass



class Design(App):
    def __init__(self, **kwargs):
        super(Design, self).__init__(**kwargs)
        self.main_hero = MainHero() # Tried main_hero = MainHero() too
        self.val = StringProperty(self.main_hero.nick)  # string

    # Construct app
    def build(self):
        # design constructor
        kv = Builder.load_file('AppDesign.kv')
        return kv

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

# Using kv 2.0
ScreenManagement:
    id: screen_manager
    FightScreen:
        name: 'FightScreen'
        manager: screen_manager
        id: fight_screen

<FightScreen>

FloatLayout:
     Label:
          text: app.val
          size_hint: .2, .2
          pos_hint: {'center_x': .5, 'center_y': .35}
     Button:
          size_hint: .2, .2
          pos_hint: {'center_x': .5, 'center_y': .5}
          on_press:
               root.rename()
          

可能可以通过properties/EventDispetcher实现.在我尝试过的许多情况下,引用app.val类似于< StringProperty name => .我尝试使用(可能是错误的)

It is probably possible through properties/EventDispetcher. Reference app.val in many cases I tried is something like <StringProperty name=>. I tried using (maybe wrong)

Aaa(EventDispetcher)类; apply_property(** kwargs)我也想用 ObjectProperty 来做到这一点,我认为这是不同的,我也不知道如何去做.

class Aaa(EventDispetcher); apply_property(**kwargs) I want to do that with ObjectProperty too, it's different I think and I have no idea how to do it.

     def rename(self):
          self.app.main_hero.nick = "Renamed"
          self.app.main_hero.num += 1
          self.app.val = self.app.main_hero  # not working need replace
          # probably something here (replacement)

class MainHero():
     def __init__(self):
          self.nick = "Player"
          self.num = 1
.
.
.
class Design(App):
     val = ObjectProperty()

     def __init__(self, **kwargs):
        super(Design, self).__init__(**kwargs)
        self.main_hero = MainHero() # Tried main_hero = MainHero() too
        self.val = self.main_hero  # object

.
.
.
Label:
     text: app.val.nick
     size_hint: .2, .2
     pos_hint: {'center_x': .5, 'center_y': .35}
Label:
     text: str(app.val.num)
     size_hint: .2, .2
     pos_hint: {'center_x': .7, 'center_y': .7}

推荐答案

必须在类方法之外定义 StringProperty

The StringProperty must be defined outside of a class method, like this:

class Design(App):
    val = StringProperty()  # defines the val property
    def __init__(self, **kwargs):
        super(Design, self).__init__(**kwargs)
        self.main_hero = MainHero()  # Tried main_hero = MainHero() too
        self.val = self.main_hero.nick  # set value of the property

然后,在您的 rename()方法中,您只需更改 app.val

Then, in your rename() method, you can just change the value of app.val

def rename(self):
    self.app.main_hero.nick = "Renamed"
    self.app.val = self.app.main_hero.nick

如果要直接在 kv 中使用 MainHero 类中的值,则它们必须为 Properties .但是要使这些属性成为 Properties MainHero 类必须是 Widget 或至少是 EventDispatcher ,例如这个:

If you want to use the values in the MainHero class directly in kv, they must be Properties. But to make those attributes into Properties, the MainHero class must be a Widget or at least an EventDispatcher, like this:

class MainHero(EventDispatcher):
    nick = StringProperty()
    num = NumericProperty()

    def __init__(self):
        self.nick = "Player"
        self.num = 1

这篇关于如何使用.py中的属性更新.kv中的标签文本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆