Python 3.x 如何在Kivy设置中禁用分区?

Python 3.x 如何在Kivy设置中禁用分区?,python-3.x,kivy,settings,Python 3.x,Kivy,Settings,我有一个带有设置的kivy应用程序,我希望为某些用户禁用一些设置(例如“常规”)。我曾尝试“走”过设置的子项(使用禁用设置),但我似乎无法做到这一点 from kivy.app import App from kivy.uix.boxlayout import BoxLayout from kivy.uix.screenmanager import Screen from kivy.uix.settings import SettingsWithSidebar import json sett

我有一个带有设置的kivy应用程序,我希望为某些用户禁用一些设置(例如“常规”)。我曾尝试“走”过设置的子项(使用禁用设置),但我似乎无法做到这一点

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import Screen
from kivy.uix.settings import SettingsWithSidebar
import json

settings_general = json.dumps([
    {'type': 'title',
     'title': 'Set general preferences'},
    {'type': 'bool',
     'title': 'Use widgets',
     'desc': 'Allow the use of widgets in the application',
     'section': 'general',
     'key': 'use widgets'},
    {'type': 'bool',
     'title': 'Print log',
     'desc': 'Print log on closing application',
     'section': 'general',
     'key': 'print log'}
     ])

settings_appearance = json.dumps([
    {'type': 'title',
     'title': 'Appearance preferences'},
    {'type': 'bool',
     'title': 'Use colour',
     'desc': 'Allow the use of colour in the application',
     'section': 'appearance',
     'key': 'use colour'}
     ])

class MainFrame(Screen):
    def __init__(self, **kwargs):
        super(MainFrame, self).__init__(**kwargs)
        pass

    def on_settings_button_click(self):
        settings = self.app.settings_cls
        print('type settings', type(settings))
        print('is SettingsWithSidebar', isinstance(settings, 
                                                   SettingsWithSidebar))
        self.app.open_settings()

    def on_quit_button_click(self):
        quit()

class Settings(object):
    def build_config(self, config):
        config.setdefaults('general',
            {
            'use widgets': 0,
            'print log': 0
            })
        config.setdefaults('appearance',
            {
            'use colour': 0
            })

    def build_settings(self, parent, settings):
        settings.add_json_panel('General',
                                parent.config,
                                data=settings_general)
        settings.add_json_panel('Appearance',
                                parent.config,
                                data=settings_appearance)

class BasicApp(App):
    def build(self):
        main_frame = MainFrame()
        main_frame.app = self
        self.settings_cls = SettingsWithSidebar
        self.use_kivy_settings = False
        return main_frame

    def build_config(self, config):
        self.settings = Settings()
        self.settings.build_config(config)

    def build_settings(self, settings):
        self.settings.build_settings(self, settings)

if __name__ == '__main__':
    BasicApp().run()
我的文件是:

<MainFrame>:
    BoxLayout:
        orientation: 'vertical'
        Button:
            text: 'Settings'
            on_press: root.on_settings_button_click()
        Button:
            text: 'Click to close'
            on_press: root.on_quit_button_click()
:
盒子布局:
方向:“垂直”
按钮:
文本:“设置”
按:根。按设置按钮单击()
按钮:
文本:“单击以关闭”
按:root。单击退出按钮
有人能建议一种我可以使用的方法吗

[本节无需阅读] 我必须输入更多的文本,然后才能发布此内容(我认为代码与文本的比率)。这似乎是一个遗憾,因为问题太简单了,我想提供一个基本的应用程序工作示例,当然,它非常详细。
[额外文本结束]

您可以使用
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'}])

本例中禁用了第二项

但是,例如,我没有找到一种直观的方法来禁用整个
外观
部分。
所以我选择了黑客方法。
首先是遍历
设置
小部件树,找到该标签

tab = list(self.app.settings.walk(loopback=True))[5]
我发现标签是本例中的第六个元素。
但仅将
disable
属性设置为
True
是不够的。它使标签变灰,但仍然可以单击它,因为他们使用了“触碰”上的
方法。
因此,我们可以在触摸屏上覆盖
方法。
为了测试这一点,我在大型机中添加了一个开关,并在app类中添加了一个toggle方法

<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()
完整代码:

从kivy.app导入应用
从kivy.uix.boxlayout导入boxlayout
从kivy.uix.screenmanager导入屏幕
从kivy.uix.settings导入设置SwithSidebar
从kivy.lang导入生成器
导入json
从functools导入部分
设置\u general=json.dumps([
{'type':'title',
“标题”:“设置常规首选项”},
{'type':'bool',
“残疾人”:正确,
“标题”:“使用小部件”,
“章节”:“概述”,
'key':'use widgets'}
])
设置\u外观=json.dumps([
{'type':'title',
“标题”:“外观首选项”},
{'type':'bool',
“标题”:“使用颜色”,
“部分”:“外观”,
“键”:“使用颜色”}
])
def on_触控向下(触控,自身):
如果不是自碰撞点(*touch.pos):
返回
self.selected=True
self.menu.selected\u uid=self.uid
类主机(屏幕):
def on_settings_button_单击(自身):
self.app.open_settings()
tab=列表(self.app.settings.walk(loopback=True))[5]
如果不是self.app.toggle:
tab.disabled=True
tab.on\u touch\u down=lambda x:False
其他:
tab.disabled=False
tab.on\u touch\u down=部分(on\u touch\u down,self=tab)
def on_退出按钮_单击(自身):
退出
生成器。加载\u字符串(“”)
:
盒子布局:
方向:“垂直”
按钮:
文本:“设置”
按:根。按设置按钮单击()
开关:
on_active:应用程序切换_设置(self.active)
按钮:
文本:“单击以关闭”
按:root。单击退出按钮
""")
类(应用程序):
toggle=False
def生成(自):
self.main=MainFrame()
self.main.app=self
self.settings\u cls=设置开关侧栏
self.use\u kivy\u设置=False
返回自主
def build_配置(自身,配置):
self.config=config
self.config.setdefaults('general',{'use widgets':0,'print log':0})
self.config.setdefaults('外观',{'use color':0})
def build_设置(自身、设置):
self.settings=设置
self.settings.add\u json\u面板('General',self.config,data=settings\u General)
self.settings.add_json_面板('Appearance',self.config,data=settings_Appearance)
def切换_设置(自、激活):
self.toggle=活动
basicap().run()

。非常感谢。不平凡。我永远也找不到它。不,我看了一下源代码。也就是说,也许我可以做一个公关,在面板上添加一个禁用的功能,这样会更容易。
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()