Kivy:从任何小部件访问配置值

R. *_*ell 7 python kivy

我正在使用 kivy 创建一个用于计算机辅助学习的小应用程序。

目前我在访问配置值时遇到了一些问题。我得到了价值

self.language = self.config.get('basicsettings', 'language')

在主应用程序类中。这工作正常,但是,我不知道如何在另一个小部件中访问这些值 - 在这种情况下是 AudioButton。

我正在使用包含屏幕的 ScreenManager。里面是一个 BoxLayout,它包含一个 GridLayout,它包含几个 AudioButton。

现在,在这个 AudioButton 中,我想知道self.languagemainApp中定义的当前值。

在 .kv 文件中,我可以做类似的事情

`text: app.language`
Run Code Online (Sandbox Code Playgroud)

得到它,但如何直接在 Python 中做到这一点?

如果我在 kv 中使用虚拟标签来获取值,它可以工作,但是当我更改设置时,我需要重新启动应用程序,因为我不知道on_config_change()在运行时需要添加什么来更新值。

我希望这是我的应用程序的一个非常简化的版本,其中包含所有有趣的部分。

class AudioButton(Button):
    filename = StringProperty(None)
    sound = ObjectProperty(None, allownone=True)

    def on_press(self):
        if self.ids.playsound.text == '1':
            self.sound.play()
        else:
            print('NoSound')


class MainScreen(Screen):
    pass


class Pictures1(GridLayout):
    def __init__(self, **kwargs):
        super(Pictures1, self).__init__(**kwargs)
        self.cols = 2
        btn = AudioButton()
        self.add_widget(btn)
        btn = AudioButton()
        self.add_widget(btn)


class Lesson1(Screen):
    pass


class ScreenManagement(ScreenManager):
    pass


class LunahutsoApp(App):
    def build(self):
        self.settings_cls = SettingsWithSidebar
        self.use_kivy_settings = False
        self.language = self.config.get('basicsettings', 'language')
        self.playsound = self.config.get('basicsettings', 'playsound')
        return ScreenManagement()

    def build_config(self, config):
        config.setdefaults('basicsettings', {
            'language': 'austrian',
            'playsound': 1})

    def build_settings(self, settings):
        settings.add_json_panel('Lunahutso',
                                self.config,
                                data=settings_json)

    def on_config_change(self, config, section,
                         key, value):
        if key == 'language':
            self.language = value
        if key == 'playsound':
            self.playsound = value


if __name__ == "__main__":
    LunahutsoApp().run()
Run Code Online (Sandbox Code Playgroud)

和 .kv 文件:

<ScreenManagement>:
    MainScreen:
    Lesson1:

<AudioButton>:
    Label:
        id: language
        text: app.language
        color: 0, 0, 0, 0
    Label:
        id: playsound
        text: app.playsound
        color: 0, 0, 0, 0

<MainScreen>:
    name: "main"
    BoxLayout:
        orientation: 'vertical'
        Button:
            on_release: app.root.current = "lesson1"
            text: "Lesson"
            font_size: 50
        Button:
            on_release: app.open_settings()
            text: "Settings"
            font_size: 50
        Button:
            on_release: sys.exit()
            text: "Quit"
            font_size: 50

<Lesson1>:
    name: "lesson1"
    id: lesson1
    BoxLayout:
        orientation: 'vertical'
        Pictures1:
            size_hint_y: 0.5
        BoxLayout:
            size_hint_y: 0.15
            Label:
                text: ""
Run Code Online (Sandbox Code Playgroud)

Pal*_*lim 5

您可以使用应用程序类的以下方法get_running_app(),请参见此处https://kivy.org/docs/api-kivy.app.html#kivy.app.App.get_running_app

这样你就可以通过 app 类从另一个类引用配置。

我在下面写了一个简单的例子。我self.text = App.get_running_app().config.get('Label','content')用来访问配置中的某个东西。

from kivy.app import App
from kivy.uix.textinput import TextInput
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.config import Config


class Labelwithconfig(Label):

    def check_label(self):
        self.text = App.get_running_app().config.get('Label','content')

kv_str = Builder.load_string("""
BoxLayout:
    orientation: 'vertical'
    Labelwithconfig:
        id: labelconf
    Button:
        text: 'open settings'
        on_press: app.open_settings()
""")



class MyApp(App):
    def build_config(self, config):
        config.setdefaults('Label', {'Content': "Default label text"})

    def build_settings(self, settings):
        settings.add_json_panel("StackOverflow Test Settings", self.config, data="""
        [
        {"type": "options",
        "title": "Label text System",
        "section": "Label",
        "key": "Content",
        "options": ["Default label text", "Other Label text"]
        }
        ]"""
        )
    def on_config_change(self, config, section, key, value):
        self.root.ids.labelconf.check_label()

    def build(self):
        return kv_str


if __name__ == '__main__':
    MyApp().run()
Run Code Online (Sandbox Code Playgroud)