Есть ли способ, чтобы свойство элемента Kivy автоматически обновлялось при изменении переменной, к которой этот элемент привязан? - PullRequest
0 голосов
/ 07 августа 2020

У меня есть приложение, в котором я хотел бы, чтобы пользователь мог изменять тему приложения и размер шрифта. У меня есть две кнопки для изменения переменных, на которых основаны такие свойства, как цвет фона кнопки и цвет текста. Как я могу сделать так, чтобы всякий раз, когда эти переменные меняются (что выполняется с помощью внешнего модуля config.py), внешний вид этих виджетов также меняется?

Вот что делает мой код: Когда "световой режим" "кнопка нажата, напишите ключ" тема "в config.ini в" свет ". Вызовите config.update_config, который считывает все значения в разделе, совпадающем с ключом «theme», который в данном случае считывает все значения в разделе «light». Присвойте эти значения переменным внутри класса «Config». "background_color" на всех кнопках привязан к "conf.accent_color", где conf является экземпляром класса Config.

Переменная, к которой привязан background_color кнопки, изменяется правильно, так как я могу получить к ней доступ внутри .kv файл. Я просто не знаю, как сделать так, чтобы цвет фона кнопки можно было обновить до новой версии переменной.

Main.py:

from kivy.lang import Builder
from kivy.properties import ListProperty, StringProperty
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.event import EventDispatcher
import config


Builder.load_file("tutorial.kv")

# declare screens


class HomeScreen(Screen):
    conf = config.Config()


class SettingsScreen(Screen):

    place_text = StringProperty()
    place_text = "hi"


class AppProject(App):
    def __init__(self):
        App.__init__(self)
        self.conf = config.Config()

    def build(self):
        sm = ScreenManager()
        sm.add_widget(HomeScreen(name='home'))
        sm.add_widget(SettingsScreen(name='settings'))
        return sm


if __name__ == '__main__':
    AppProject().run()

main.kv :

#:set max_menu_button_scale '500dp', '450dp'
#:set min_menu_button_scale '400dp', '200dp'
#:import cfg config
#:import configparser configparser


<HomeScreen>:
    canvas.before:
        Color:
            rgba: app.conf.background_color
        Rectangle:
            pos: self.pos
            size: self.size
    GridLayout:
        cols: 1
        pos_hint: {"center_x":0.5 , "center_y":0.5}
        size_hint: 0.5, 0.5
        spacing: '30dp'
        size_hint_max: max_menu_button_scale
        size_hint_min: min_menu_button_scale

        MenuButton:
            text: "New Solution"
        MenuButton:
            text: "Solution History"
        MenuButton:
            text: "Settings"

            on_press:
                root.manager.transition.direction = 'up'
                root.manager.current = 'settings'

<SettingsScreen>:
    canvas.before:
        Color:
            rgba: app.conf.background_color
        Rectangle:
            pos: self.pos
            size: self.size
    GridLayout:
        cols:1
        Label:
            text: root.place_text
        MenuButton:
            text: "Back"
            on_press:
                root.manager.transition.direction = 'up'
                root.manager.current = 'home'
        GridLayout:
            cols:2
            Button:
                text: "Light"
                color: cfg.hex_to_rgba_01(app.conf.config['LIGHT']['text_color'])
                background_normal: 'assets/16px_rounded_button.png'
                background_down: 'assets/16px_rounded_button_pressed.png'
                background_color: cfg.hex_to_rgba_01(app.conf.config['LIGHT']['accent_color'])
                on_press:
                    app.conf.config['SETTINGS']['theme'] = "light"
                    app.conf.config.write(open('settings.ini', 'w'))

            Button:
                text: "Dark"
                color: cfg.hex_to_rgba_01(app.conf.config['DARK']['text_color'])
                background_normal: 'assets/16px_rounded_button.png'
                background_down: 'assets/16px_rounded_button_pressed.png'
                background_color: cfg.hex_to_rgba_01(app.conf.config['DARK']['accent_color'])
                on_press:
                    app.conf.config['SETTINGS']['theme'] = "dark"
                    app.conf.config.write(open('settings.ini', 'w'))
                    app.conf.update_config()


<MenuButton@Button>:
    font_size: app.conf.config["SETTINGS"]["font_size"]
    color: app.conf.text_color
    background_normal: 'assets/16px_rounded_button.png'
    background_down: 'assets/16px_rounded_button_pressed.png'
    background_color: app.conf.accent_color


config.py

import configparser
import copy

from kivy.properties import ListProperty, StringProperty, Property


def hex_to_rgba_01(value):
    value = value.lstrip('#')
    lv = len(value)
    r, g, b = tuple(int(value[i:i + lv // 3], 16) for i in range(0, lv, lv // 3))
    r /= 255
    g /= 255
    b /= 255
    a = 1
    return [r, g, b, a]

class Config:
    config = configparser.ConfigParser()

    def write_default_settings(self):
        self.config["SETTINGS"] = {'theme': 'light', 'font_size': '40dp'}
        self.config["LIGHT"] = {}
        #   DEFINE DEFAULT VALUES HERE
        light = self.config["LIGHT"]
        light['accent_color'] = "#f5f5f5"
        light['background_color'] = "#e0e0e0"
        light['text_color'] = "#212121"

        self.config["DARK"] = {}
        #   DEFINE DEFAULT VALUES HERE
        dark = self.config["DARK"]
        dark['accent_color'] = "#303030"
        dark['background_color'] = "#212121"
        dark['text_color'] = "#f5f5f5"
        with open('settings.ini', 'w+') as configfile:
            self.config.write(configfile)

    def __init__(self):
        try:
            f = open("settings.ini", 'r')
        except FileNotFoundError:
            self.write_default_settings()
        self.config.read('settings.ini')
        # reference these vars
        theme = self.config["SETTINGS"]["theme"]
        font_size = self.config["SETTINGS"]["font_size"]
        theme_reference = theme.upper()

        self.accent_color = ListProperty()
        self.accent_color = hex_to_rgba_01(self.config[theme_reference]["accent_color"])
        self.background_color = ListProperty()
        self.background_color = hex_to_rgba_01(self.config[theme_reference]["background_color"])
        self.text_color = ListProperty()
        self.text_color = hex_to_rgba_01(self.config[theme_reference]["text_color"])
        print(self.accent_color)

    def update_config(self):

        theme = self.config["SETTINGS"]["theme"]
        theme_reference = theme.upper()
        self.accent_color = hex_to_rgba_01(self.config[theme_reference]["accent_color"])
        self.background_color = hex_to_rgba_01(self.config[theme_reference]["background_color"])
        self.text_color = hex_to_rgba_01(self.config[theme_reference]["text_color"])

config.ini:

[SETTINGS]
theme = dark
font_size = 40dp

[LIGHT]
accent_color = #f5f5f5
background_color = #e0e0e0
text_color = #212121

[DARK]
accent_color = #303030
background_color = #212121
text_color = #f5f5f5
...