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

时间:2017-08-13 18:59:35

标签: python kivy

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

目前我在访问配置值方面遇到了一些问题。 我用

得到了价值

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

在主App-Class中。这工作正常,但是,我不知道如何在另一个小部件中访问这些值 - 在本例中是AudioButton。

我正在使用包含Screen的ScreenManager。 Inside是一个BoxLayout,它包含一个GridLayout,它包含几个AudioButtons。

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

在.kv文件中,我可以执行类似

的操作
`text: app.language`

得到它,但如何直接在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()

.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: ""

2 个答案:

答案 0 :(得分:1)

您可以使用应用类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()

答案 1 :(得分:1)

App.get_running_app().config的替代方法是使用ConfigParser.get_configparser('app')

这会直接为您提供配置对象。

一个甚至更好的方法,如果你想绑定到这些值,或者只是查看一次,那就是使用ConfigParserProperty

这样您就可以直接将配置中的值用作属性,而无需自行处理配置或监控配置更改:

class LunahutsoApp(App):
    language = ConfigParserProperty('austrian', 
                    'basicsettings', 'language', 'app')
    playsound = ConfigParserProperty(1, 
                    'basicsettings', 'playsound', 'app')

    ...

然后你可以绑定Kv中的值(注意:你定义的方式langaugeplaysound,你的Kv标签不会自动更新,因为它们不是属性):

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

您还可以在任何屏幕或窗口小部件(不仅仅是应用程序)上定义ConfigParserProperty

class AudioButton(Button):
    filename = StringProperty(None)
    sound = ObjectProperty(None, allownone=True)
    playsound = ConfigParserProperty('1', 
                    'basicsettings', 'playsound', 'app')


<AudioButton>:
    Label:
        id: language
        text: app.language
        color: 0, 0, 0, 0
    Label:
        text: self.playsound
        color: 0, 0, 0, 0
        on_press: if self.playsound == '1': self.sound.play()