【问题标题】:How to update label text in .kv using properties in .py?如何使用 .py 中的属性更新 .kv 中的标签文本?
【发布时间】:2021-05-04 20:40:32
【问题描述】:

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

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 类似于 。 我尝试使用(可能是错误的)

class Aaa(EventDispetcher); apply_property(**kwargs) 我也想用ObjectProperty 做到这一点,我认为它是不同的,我不知道该怎么做。

编辑:

     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}

【问题讨论】:

    标签: python kivy kivy-language


    【解决方案1】:

    StringProperty 必须在类方法之外定义,如下所示:

    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 的值

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

    如果您想直接在kv 中使用MainHero 类中的值,它们必须是Properties。但是要将这些属性变成PropertiesMainHero 类必须是Widget 或至少是EventDispatcher,如下所示:

    class MainHero(EventDispatcher):
        nick = StringProperty()
        num = NumericProperty()
    
        def __init__(self):
            self.nick = "Player"
            self.num = 1
    

    【讨论】:

    • NumericProperty也有效,但不能使用f string,需要通过str()转换成in .kv我>
    • 如果我直接在 .kv 中访问属性,这是否适用于 ObjectProperty?我试过但无法弄清楚,可能你知道
    • 适用于任何Property,但您必须清楚您使用它的目的。正如@master 指出的那样,只要将Labeltext 转换为字符串,就可以使用NumericProperty。同样,如果您使用ObjectProperty,则必须从引用的对象中提取适当类型的对象。
    • 我知道你的意思,我试过了但没有用,看看我的编辑
    • 问题是kivy做的自动更新只对Properties有效,而MainHeronicknum属性不是Properties。尝试按照我更新的答案更改您的 MainHero 课程。
    【解决方案2】:

    您需要在kv文件中为标签指定一个ID,并将您要更改文本的操作引用到回调函数,然后以这种方式更改标签的文本。

    kv:

    MDLabel:
            id: number
            text: "1"
            halign: "center"
            pos_hint: {"center_x": .5, "center_y": .5}
    

    py:

    class Screen2(Screen, n):
        def set_number(self):
            self.ids.number.text = f"{n}"
    

    【讨论】:

    • 我知道这种方式,我写了我不能这样做
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-09
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 2020-04-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多