我正试图在Kivy应用程序中实现一个手动创建的设置页面。在这种情况下,我在应用程序内部使用实现的设置时遇到了问题。为了证明这个问题,请使用这个最小的例子:
Python文件"main.py",我试图在其中将当前字体大小写入两个全局变量firstrongize和second_size中,然后我想在Kivy文件lateron:中访问它们
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from settingsjson import settings_json
from kivy.properties import NumericProperty
import settings
class MainMenu(Screen):
pass
class ScreenManagement(ScreenManager):
pass
presentation = Builder.load_file("style.kv")
class MyApp(App):
def build(self):
global first_size, second_size
first_size = NumericProperty(settings.sizes[settings.options[0]]["first_label"])
second_size = NumericProperty(settings.sizes[settings.options[0]]["second_label"])
return presentation
def build_config(self, config):
config.setdefaults('settings', {
'test_size': settings.options[0]
})
def build_settings(self, settings):
settings.add_json_panel('Own Settings',
self.config,
data=settings_json)
def reset_labels(self, first_labelsize, second_labelsize):
global first_size, second_size
first_size = NumericProperty(first_labelsize)
second_size = NumericProperty(second_labelsize)
def on_config_change(self, config, section, key, value):
first_labelsize = settings.sizes[value]['first_label']
second_labelsize = settings.sizes[value]['second_label']
self.reset_labels(first_labelsize, second_labelsize)
myApp = MyApp()
myApp.run()
Python文件"settingsjson.py",包含新的设置页面:
import json
import settings
settings_json = json.dumps([
{'type': 'title',
'title': 'Settings'},
{'type': 'options',
'title': 'Size',
'desc': 'Test size',
'options': settings.options,
'section': 'settings',
'key': 'test_size'}])
Python文件"settings.py"用于将设置菜单中的两个选项与字体大小关联起来的字典:
options = ['small', 'large']
small = {'first_label': 20, 'second_label': 15}
large = {'first_label': 30, 'second_label': 25}
sizes = {options[0]: small, options[1]: large}
最后是Kivy文件"style.kv":
ScreenManagement:
MainMenu:
## accessing first global variable (not working)
<Button>:
font_size: root.first_size
## accessing second global variable (not working either)
<TwoLineButton@Button>:
font_size: root.second_size
<MainMenu>:
name: "main"
FloatLayout:
Button:
size_hint: 0.5, 0.2
pos_hint: {"top": 0.5, "right": 1}
text: "One-line dummy"
TwoLineButton:
size_hint: 0.5, 0.2
pos_hint: {"top": 0.5, "left": 1}
text: "This is a two-linen dummy"
halign: "center"
Button:
on_release:
app.open_settings()
text: "Settings"
font_size: self.height/4
pos_hint: {"top": 0.1, "right": 0.5}
size_hint: 0.2, 0.1
正如您所看到的,当前形式的代码不起作用,因为我无法访问Kivy文件中的两个字体大小变量。如果我将Kivy文件中的font_size属性设置为常数值,应用程序运行时不会出现问题,但当然不允许设置菜单中的更改生效。
有没有办法访问Kivy文件中main.py文件中的全局变量来重置这两种按钮的字体大小?
由于我必须在不止一个屏幕上更改设置,我需要一个全局类独立的解决方案。
我很感激每一种暗示。。。
这里有一种略有不同的方法,当数字属性发生更改时,使用on_回调自动更改字体大小。请注意,必须在加载style.kv 之前定义firstrongize和second_size
Main.py:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from settingsjson import settings_json
from kivy.properties import NumericProperty
import settings
class MainMenu(Screen):
pass
class ScreenManagement(ScreenManager):
pass
class MyApp(App):
first_size = NumericProperty(settings.sizes[settings.options[0]]["first_label"])
second_size = NumericProperty(settings.sizes[settings.options[0]]["second_label"])
def on_first_size(self, instance, value):
self.main_menu.ids['button1'].font_size = value
def on_second_size(self, instance, value):
self.main_menu.ids['button2'].font_size = value
def build(self):
presentation = Builder.load_file("style.kv")
self.main_menu = presentation.current_screen
return presentation
def build_config(self, config):
config.setdefaults('settings', {
'test_size': settings.options[0]
})
def build_settings(self, settings):
settings.add_json_panel('Own Settings',
self.config,
data=settings_json)
def on_config_change(self, config, section, key, value):
self.first_size = settings.sizes[value]['first_label']
self.second_size = settings.sizes[value]['second_label']
myApp = MyApp()
myApp.run()
和style.kv:
ScreenManagement:
MainMenu:
<MainMenu>:
name: "main"
FloatLayout:
Button:
id: button1
font_size: app.first_size
size_hint: 0.5, 0.2
pos_hint: {"top": 0.5, "right": 1}
text: "One-line dummy"
Button:
id: button2
font_size: app.second_size
size_hint: 0.5, 0.2
pos_hint: {"top": 0.5, "left": 1}
text: "This is a two-linen dummy"
halign: "center"
Button:
on_release:
app.open_settings()
text: "Settings"
font_size: self.height/4
pos_hint: {"top": 0.1, "right": 0.5}
size_hint: 0.2, 0.1
不确定这是否适用于您,但在.kv文件中删除您的Button和TwoLineButton定义,并从布局中的实际Button定义中访问root.firstrongize和root.second_size:
FloatLayout:
Button:
font_size: root.first_size
size_hint: 0.5, 0.2
pos_hint: {"top": 0.5, "right": 1}
text: "One-line dummy"
Button:
font_size: root.second_size
size_hint: 0.5, 0.2
pos_hint: {"top": 0.5, "left": 1}
text: "This is a two-linen dummy"
halign: "center"
它引用的"根"是"MainMenu",因此在MainMenu类中添加类级变量"firstrongize"one_answers"second_size":
class MainMenu(Screen):
first_size = NumericProperty(settings.sizes[settings.options[0]]["first_label"])
second_size = NumericProperty(settings.sizes[settings.options[0]]["second_label"])
由于这些不是实例变量,您可以从导入MainMenu的任何位置将它们引用为"MainMenu.firstrongize"one_answers"MainMenu.second_size"。