У меня есть приложение, в котором я хотел бы, чтобы пользователь мог изменять тему приложения и размер шрифта. У меня есть две кнопки для изменения переменных, на которых основаны такие свойства, как цвет фона кнопки и цвет текста. Как я могу сделать так, чтобы всякий раз, когда эти переменные меняются (что выполняется с помощью внешнего модуля 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