Вы можете отключить элементы на панели с атрибутом disabled
.
settings_general = json.dumps([
{'type': 'title',
'title': 'Set general preferences'},
{'type': 'bool',
'disabled': True,
'title': 'Use widgets',
'desc': 'Allow the use of widgets in the application',
'section': 'general',
'key': 'use widgets'}])
Второй элемент отключен в этом примере.
Однако я не нашел, например, интуитивно понятного способа отключить весь раздел Appearance
.
Итак, я выбрал хакерский метод.
Сначала нужно было пройтись по виджету settings
дерево, чтобы найти этот ярлык.
tab = list(self.app.settings.walk(loopback=True))[5]
Я обнаружил, что в данном случае метка является 6-м элементом.
Но этого было недостаточно, чтобы установить для атрибута disable
значение True
.Он выделяет метку, но по-прежнему работает, чтобы щелкнуть по ней, поскольку они использовали метод on_touch_down
.
Таким образом, мы можем переопределить метод on_touch_down
.
Я добавил переключатель на мэйнфрейм и метод переключенияв классе приложения, чтобы проверить это.
<MainFrame>:
BoxLayout:
orientation: 'vertical'
Button:
text: 'Settings'
on_press: root.on_settings_button_click()
Switch:
on_active: app.toggle_setting(self.active)
Button:
text: 'Click to close'
on_press: root.on_quit_button_click()
Я нашел оригинальный метод on_touch_down здесь
def on_touch_down(touch, self):
# we need to write this method to override back to the original method
# the original method was found in kivy/uix/settings.py.
# look at the link above
if not self.collide_point(*touch.pos):
return
self.selected = True
self.menu.selected_uid = self.uid
class MainFrame(Screen):
def on_settings_button_click(self):
self.app.open_settings()
tab = list(self.app.settings.walk(loopback=True))[5]
if not self.app.toggle: # if switch is inactive
tab.disabled = True
tab.on_touch_down = lambda x: False
else:
tab.disabled = False
# we need partial from functools, so we can pass the tab as self
tab.on_touch_down = partial(on_touch_down,self=tab)
def on_quit_button_click(self):
quit()
Полный код:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import Screen
from kivy.uix.settings import SettingsWithSidebar
from kivy.lang import Builder
import json
from functools import partial
settings_general = json.dumps([
{'type': 'title',
'title': 'Set general preferences'},
{'type': 'bool',
'disabled': True,
'title': 'Use widgets',
'section': 'general',
'key': 'use widgets'}
])
settings_appearance = json.dumps([
{'type': 'title',
'title': 'Appearance preferences'},
{'type': 'bool',
'title': 'Use colour',
'section': 'appearance',
'key': 'use colour'}
])
def on_touch_down(touch, self):
if not self.collide_point(*touch.pos):
return
self.selected = True
self.menu.selected_uid = self.uid
class MainFrame(Screen):
def on_settings_button_click(self):
self.app.open_settings()
tab = list(self.app.settings.walk(loopback=True))[5]
if not self.app.toggle:
tab.disabled = True
tab.on_touch_down = lambda x: False
else:
tab.disabled = False
tab.on_touch_down = partial(on_touch_down,self=tab)
def on_quit_button_click(self):
quit()
Builder.load_string("""
<MainFrame>:
BoxLayout:
orientation: 'vertical'
Button:
text: 'Settings'
on_press: root.on_settings_button_click()
Switch:
on_active: app.toggle_setting(self.active)
Button:
text: 'Click to close'
on_press: root.on_quit_button_click()
""")
class BasicApp(App):
toggle = False
def build(self):
self.main = MainFrame()
self.main.app = self
self.settings_cls = SettingsWithSidebar
self.use_kivy_settings = False
return self.main
def build_config(self, config):
self.config = config
self.config.setdefaults('general',{'use widgets': 0,'print log': 0})
self.config.setdefaults('appearance',{'use colour': 0})
def build_settings(self, settings):
self.settings = settings
self.settings.add_json_panel('General', self.config, data=settings_general)
self.settings.add_json_panel('Appearance', self.config, data = settings_appearance)
def toggle_setting(self, active):
self.toggle = active
BasicApp().run()