Kivy Label.text 属性不会在 UI 上更新
Posted
技术标签:
【中文标题】Kivy Label.text 属性不会在 UI 上更新【英文标题】:Kivy Label.text Property doesn't update on the UI 【发布时间】:2014-08-09 21:55:36 【问题描述】:我遇到了标签的更新文本属性在我的 UI 上未正确显示的问题。我检查了 text 属性,可以验证它是否被设置为新值,但在呈现标签时该值没有显示。
标签位于另一个屏幕上,我正在使用 ScreenManager 切换到该屏幕。屏幕的 Sub Widgets 和树是在单独的 .kv 文件中构建的(我在示例中使用了 load_string() Builder 方法,但结果相同)
这是一个简单的例子:
from kivy.config import Config
Config.set('graphics', 'width', '300')
Config.set('graphics', 'height', '200')
Config.set('graphics', 'resizable', '0')
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
Builder.load_string("""
<screen1>:
Button:
id: button
text: 'Press me to Update Screen2'
on_press:
root.update_screen2()
<screen2>:
Label:
id: mainLabel
text: 'I have not been updated'
""")
class screen1(Screen):
def __init__(self, **kwargs):
"""
Set super and store the id of the button
"""
super(screen1, self).__init__(**kwargs)
self.button = self.ids.button.__self__
return
def update_screen2(self):
"""
send text 1 and text 2 to the screen2 object
for it to set on it's label
"""
text1 = 'Hi There'
text2 = 'Does this work'
screen2.update_label(screen2(),text1, text2)
return
class screen2(Screen):
def __init__(self, **kwargs):
"""
set super ond store the id of the label
"""
super(screen2, self).__init__(**kwargs)
self.mainLabel = self.ids.mainLabel.__self__
return
def update_label(self, text1, text2):
"""
using text1 and text2, update the text property of the label
the output of each print() shows the text property is being updated
it just doesn't display on the UI
"""
print(self.mainLabel.text)
self.mainLabel.text = text1 + '\n\n' + text2
print(self.mainLabel.text)
screenManager.current = 'screen2'
return
screenManager = ScreenManager()
class MainApp(App):
def build(self):
#root widget is abox layout
self.root = BoxLayout()
#instantiate the screen objects
self.screen1 = screen1(name='screen1')
self.screen2 = screen2(name='screen2')
#add the screens to the screenManager
screenManager.add_widget(self.screen1)
screenManager.add_widget(self.screen2)
#set the current screen
screenManager.current = 'screen1'
#add the screenManager to the root widget and return it
self.root.add_widget(screenManager)
return self.root
if __name__ == '__main__':
MainApp().run()
我尝试了各种方法,例如更改我在 python 中引用标签小部件的方式、要求画布更新或创建一个“screen2()”对象以从 screen1 中调用该方法,但无济于事。 我错过了什么?
【问题讨论】:
【参考方案1】:screen2.update_label(screen2(),text1, text2)
这一行并不像你想象的那样——实际上,它犯了多个错误,你熟悉 python 类的工作原理吗?
首先,当您调用一个方法时,您通常希望使用该类的实例来执行此操作,例如
a = [1, 2, 3]
a.append(10)
这会将 10 追加到列表的这个 instance。
你所做的不是调用类实例的update_label方法,而是直接用类定义和新实例screen2()
调用。由于这不会为您崩溃,我认为如果您传入要更改的实例,它可能会起作用,但这不正常,没有理由这样做。问题是您更改了传入的新 screen2 实例的文本,但这与您在应用中实际显示的对象完全不同,因此您看不到任何变化。
您需要调用您的应用实际使用的 screen2 实例的 update_label 方法。例如,以下内容应该可以工作:
screen2_instance = self.parent.get_screen('screen2')
screen2_instance.update_label(text1, text2)
第一行使用屏幕管理器的 get_screen 方法来检索名称为“screen2”的现有屏幕。第二行使用您的新文本调用其更新标签方法。请注意,您不传入屏幕实例参数(称为self
) - 实例方法会自动接收第一个参数。
你还应该大写你的类名,因为它是一个 python 约定(这显然不是强制性的,但要遵循一般社区风格指南有很多话要说),而且因为 kv 语言使用这种大写来标识小部件,所以如果你不这样做,你以后可能会遇到问题。
【讨论】:
太棒了,谢谢。当我这样做时,我觉得一切都错了(这个例子只是许多迭代的最后一次)。我没有尝试过的一件事是直接从 ScreenManager 获取对屏幕的引用。添加 'screen2 = screenManager.get_screen('screen2') 完成了这项工作。 也感谢有关大写的指针。我一直在使用带有初始小写字母的 CamelCase,但会立即更改。以上是关于Kivy Label.text 属性不会在 UI 上更新的主要内容,如果未能解决你的问题,请参考以下文章