在 Kivy 中跨屏幕更新标签 (Python) - .kv 和 .py 文件与 ScreenManager 之间(缺乏)交互的问题
Updating Labels across Screens in Kivy (Python) - Problem with (lack of) interactions between .kv and .py files with ScreenManager
我正在尝试构建一个 Kivy 应用程序,它有 2 个屏幕,这些屏幕用不同的文本一遍又一遍地重复使用。
所以我从标签为“First1”的 FirstScreen 转到标签为“Second1”的 SecondScreen,然后回到 FirstScreen,但这次标签为“First2”,然后是 SecondScreen 和“Second2”,依此类推。
此代码非常简单,但在没有指定更新按钮的情况下更新标签文本似乎存在问题。出于某种原因,我的 Python 代码设法更新了文本,但它没有在我的 .kv 文件中更新。因此,例如,我的打印语句会告诉我标签文本是“First2”,但 Kivy 为我显示“First1”。我在下面的屏幕截图中说明了这一点:
通过添加一个在按下时更新文本的按钮,所有内容都会更新、同步并正常工作,但我真的希望它在没有额外用户输入的情况下也能正常工作。有人知道我该怎么做吗?我已经左右搜索了文档和 Whosebug 问题,但似乎找不到我看似简单的问题的答案。
代码如下:
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import StringProperty, ObjectProperty
from kivy.lang import Builder
S_ID = 1 # global screen ID. I'm using this to detect what text to use.
class FirstScreen(Screen):
text = StringProperty("")
lbl = ObjectProperty(None)
def __init__(self, **kwargs):
super(FirstScreen, self).__init__(**kwargs)
global S_ID
print("\nS_ID is ", S_ID)
self.update()
def update(self):
print("FIRST - UPDATE")
if S_ID == 1:
print("FIRST1")
self.text = "FIRST1"
elif S_ID == 2:
print("FIRST2")
self.text = "FIRST2"
print("self.lbl.text", self.lbl.text)
else:
print("FIRST ELSE")
self.text = "FIRST ELSE"
def pressed(self):
sm.current = "second"
class SecondScreen(Screen):
text = StringProperty("")
def __init__(self, **kwargs):
super(SecondScreen, self).__init__(**kwargs)
self.update()
def update(self):
print("SECOND - UPDATE")
if S_ID == 1:
print("SECOND1")
self.text = "SECOND1"
elif S_ID == 2:
print("SECOND2")
self.text = "SECOND2"
else:
print("SECOND ELSE")
self.text = "SECOND ELSE"
def pressed(self):
global S_ID
S_ID += 1
FirstScreen.update(FirstScreen())
sm.current = "first"
sm = ScreenManager()
kv = Builder.load_file("test.kv")
sm.add_widget(FirstScreen(name='first'))
sm.add_widget(SecondScreen(name='second'))
sm.current = "first"
class MyApp(App):
def build(self):
return sm
if __name__ == '__main__':
MyApp().run()
这是 .kv 文件:
<FirstScreen>:
name: "first"
lbl: lbl:
GridLayout:
cols:2
Label:
id: lbl
text: root.text
Button:
text: "next"
on_press: root.pressed()
<SecondScreen>:
name: "second"
GridLayout:
cols:2
Label:
text: root.text
Button:
text: "next"
on_press:
root.pressed()
问题是你的陈述:
FirstScreen.update(FirstScreen())
此语句正在创建 FirstScreen
的新实例并更新该实例。不幸的是,该实例不是您的 GUI 中显示的实例。您可以通过将上述语句替换为:
来更正该错误
first_screen = self.manager.get_screen('first')
first_screen.update()
此代码从 ScreenManager
获取 FirstScreen
的实例并在该实例上调用 update()
。
我正在尝试构建一个 Kivy 应用程序,它有 2 个屏幕,这些屏幕用不同的文本一遍又一遍地重复使用。
所以我从标签为“First1”的 FirstScreen 转到标签为“Second1”的 SecondScreen,然后回到 FirstScreen,但这次标签为“First2”,然后是 SecondScreen 和“Second2”,依此类推。
此代码非常简单,但在没有指定更新按钮的情况下更新标签文本似乎存在问题。出于某种原因,我的 Python 代码设法更新了文本,但它没有在我的 .kv 文件中更新。因此,例如,我的打印语句会告诉我标签文本是“First2”,但 Kivy 为我显示“First1”。我在下面的屏幕截图中说明了这一点:
通过添加一个在按下时更新文本的按钮,所有内容都会更新、同步并正常工作,但我真的希望它在没有额外用户输入的情况下也能正常工作。有人知道我该怎么做吗?我已经左右搜索了文档和 Whosebug 问题,但似乎找不到我看似简单的问题的答案。
代码如下:
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import StringProperty, ObjectProperty
from kivy.lang import Builder
S_ID = 1 # global screen ID. I'm using this to detect what text to use.
class FirstScreen(Screen):
text = StringProperty("")
lbl = ObjectProperty(None)
def __init__(self, **kwargs):
super(FirstScreen, self).__init__(**kwargs)
global S_ID
print("\nS_ID is ", S_ID)
self.update()
def update(self):
print("FIRST - UPDATE")
if S_ID == 1:
print("FIRST1")
self.text = "FIRST1"
elif S_ID == 2:
print("FIRST2")
self.text = "FIRST2"
print("self.lbl.text", self.lbl.text)
else:
print("FIRST ELSE")
self.text = "FIRST ELSE"
def pressed(self):
sm.current = "second"
class SecondScreen(Screen):
text = StringProperty("")
def __init__(self, **kwargs):
super(SecondScreen, self).__init__(**kwargs)
self.update()
def update(self):
print("SECOND - UPDATE")
if S_ID == 1:
print("SECOND1")
self.text = "SECOND1"
elif S_ID == 2:
print("SECOND2")
self.text = "SECOND2"
else:
print("SECOND ELSE")
self.text = "SECOND ELSE"
def pressed(self):
global S_ID
S_ID += 1
FirstScreen.update(FirstScreen())
sm.current = "first"
sm = ScreenManager()
kv = Builder.load_file("test.kv")
sm.add_widget(FirstScreen(name='first'))
sm.add_widget(SecondScreen(name='second'))
sm.current = "first"
class MyApp(App):
def build(self):
return sm
if __name__ == '__main__':
MyApp().run()
这是 .kv 文件:
<FirstScreen>:
name: "first"
lbl: lbl:
GridLayout:
cols:2
Label:
id: lbl
text: root.text
Button:
text: "next"
on_press: root.pressed()
<SecondScreen>:
name: "second"
GridLayout:
cols:2
Label:
text: root.text
Button:
text: "next"
on_press:
root.pressed()
问题是你的陈述:
FirstScreen.update(FirstScreen())
此语句正在创建 FirstScreen
的新实例并更新该实例。不幸的是,该实例不是您的 GUI 中显示的实例。您可以通过将上述语句替换为:
first_screen = self.manager.get_screen('first')
first_screen.update()
此代码从 ScreenManager
获取 FirstScreen
的实例并在该实例上调用 update()
。