在screenmanager对象中引用id

时间:2016-03-15 19:08:02

标签: python kivy

我试图绕过屏幕管理器,尤其是引用其中的对象。

我曾经用它来设置一个值:

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()

3 个答案:

答案 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建议类的子类应该是类的更具体的形式。因此,ScreenWidget类型。但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