我试图绕过屏幕管理器,尤其是引用其中的对象。
我曾经用它来设置一个值:
class Widgets(Widget)
pass
w = Widgets()
w.ids.MyTitle.text = 'something'
现在我有了这个:
class Widgets(Screen)
pass
class SettingsScreen(Screen)
pass
sm = ScreenManager()
sm.add_widget(Widgets(name='main'))
sm.add_widget(SettingsScreen(name='settings'))
我现在如何参考MyTitle?我尝试过各种各样的组合,例如:
sm.ids.main.MyTitle.text =
sm.main.MyTitle.text =
sm.main.ids.MyTitle.text =
....但没有得到它!有人能让我摆脱苦难吗?是否有一种简单的方法可以浏览sm对象或迭代它?
编辑:添加最小运行版本:
minimal.kv:
# File name: minimal.py
#:kivy 1.8.0
<Widgets>
Button:
id: MyTitle
text: 'hello'
<SettingsScreen>:
Button:
id: Other
text: 'settings'
minimal.py:
from kivy.uix.widget import Widget
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.uix.button import Button
from kivy.lang import Builder
from kivy.app import App
class Widgets(Screen):
pass
class SettingsScreen(Screen):
pass
class myApp(App):
def build(self):
return sm
def on_start(self):
global sm
sm.ids['main'].ids['MyTitle'].text = 'changed' # <-- this fails
Builder.load_file("minimal.kv")
sm = ScreenManager()
sm.add_widget(Widgets(name='main'))
sm.add_widget(SettingsScreen(name='settings'))
if __name__ == '__main__':
myApp().run()
答案 0 :(得分:1)
要从ScreenManager
获取屏幕,请使用get_screen
:
sm.get_screen('main').ids.MyTitle.text = 'changed'
此外,您可以构建您的应用程序: kv文件:
# File name: minimal.py
#:kivy 1.8.0
ScreenManager:
Widgets:
name: 'main'
SettingsScreen:
name: 'settings'
<Widgets>:
Button:
id: MyTitle
text: 'hello'
<SettingsScreen>:
Button:
id: Other
text: 'settings'
并在python文件中:
sm=Builder.load_file(..)
class my12App(App):
def build(self):
return sm
def on_start(self):
self.root.get_screen('main').ids.MyTitle.text = 'changed'
答案 1 :(得分:0)
根据the documentation,您可以像访问字典键一样访问id
:
widget.ids['MyTitle']
因为ScreenManager
本身来自Widget
,并且给定的小部件维护a list of widgets it is aware of,所以您可能需要以下内容:
sm.ids[0].ids['MyTitle'].text
然而,如果没有Minimal, Complete, and Verifiable Example,这很难说。你能做的一件事是:
for id in sm.ids: # Iterate through all widgets in ids
print(id) # Get the string representation of that widget
作为旁注,这是:
class Widgets(Screen)
pass
...可能会引起混淆,因为您使用Widget
(通过中间类Widgets
)扩展Screen
。 OOP建议类的子类应该是类的更具体的形式。因此,Screen
是Widget
的类型。但Widgets
实际上是Widgets
的数字。
答案 2 :(得分:0)
不幸的是,问题中的代码或接受的答案中的代码都不适合我,而且我不确定应该的工作原理。我对此的解释是,OP希望基于来自另一个屏幕的回调来更改一个屏幕内的小部件(按钮)的属性。以下代码是 complete 的MWE:
# File name: minimal.py
#:kivy 2.0.0
ScreenManager:
FoobarScreen:
name: 'foobar'
Widgets:
name: 'widgets'
<FoobarScreen>:
Button:
id: lalala
text: 'lalala'
<Widgets>:
Button:
id: lololo
text: 'lololo'
(minimal.kv
)
import kivy
from kivy.uix.widget import Widget
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.uix.button import Button
from kivy.lang import Builder
from kivy.app import App
class FoobarScreen(Screen):
pass
class Widgets(Screen):
pass
class myApp(App):
def build(self):
return sm
def on_start(self):
self.root.get_screen('widgets').ids.lololo.text = 'changed'
self.root.current = 'widgets'
if __name__ == '__main__':
sm=Builder.load_file('minimal.kv')
myApp().run()
(minimal.py
)