Python 基维:如果屏幕上的更改没有保存,我如何清除它们

Python 基维:如果屏幕上的更改没有保存,我如何清除它们,python,events,kivy,Python,Events,Kivy,我目前有一个主页和一个设置页面。在screen manager中,当我转到“设置”页面并在未单击“保存”按钮的情况下更改值并离开“设置”页面时,设置似乎已保存给最终用户,因为当他们返回该屏幕时,他们的更改仍会反映出来,而他们没有单击“保存”。我如何处理这个问题 我尝试清除小部件并重新创建它们,但失败了。似乎Kivy在运行一个on\u pre\u enter事件的同时运行了一个on\u pre\u leave事件。若要解决此问题,最好在退出屏幕时保存设置,或在退出屏幕时清除更改,而不单击“保存”。

我目前有一个主页和一个设置页面。在screen manager中,当我转到“设置”页面并在未单击“保存”按钮的情况下更改值并离开“设置”页面时,设置似乎已保存给最终用户,因为当他们返回该屏幕时,他们的更改仍会反映出来,而他们没有单击“保存”。我如何处理这个问题

我尝试清除小部件并重新创建它们,但失败了。似乎Kivy在运行一个
on\u pre\u enter
事件的同时运行了一个
on\u pre\u leave
事件。若要解决此问题,最好在退出屏幕时保存设置,或在退出屏幕时清除更改,而不单击“保存”。请帮助:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.switch import Switch
from kivy.core.window import Window
from kivy.uix.progressbar import ProgressBar
from kivy.clock import Clock

Window.clearcolor = (252, 235, 233, 0)
#!/usr/bin/python3

class MyScreenManager(ScreenManager):
    pass


class LoginPageScreen(Screen):
    pass
class UserSettingsScreen(Screen):
    pass

class LoginPage(BoxLayout):
    def __init__(self, **kwargs):
        super(LoginPage, self).__init__(**kwargs)

        self.add_widget(Label(text="[color=000000][b]Main page[/b][/color]", markup=True, size_hint_y=None, font_size='15sp'))

class UserSettings(BoxLayout):
    def __init__(self, **kwargs):
        super(UserSettings, self).__init__(**kwargs)
        # self.clear_widgets()
        on_pre_enter = self.userSettingsClass()
        # on_pre_leave = self.userSettingsClass()

    def userSettingsClass(self):
        # self.clear_widgets()

        self.add_widget(Label(text="[color=000000][b]settings[/b][/color]", markup=True, font_size='15sp'))
        self.testSwitch = Switch()
        self.add_widget(self.testSwitch)

        self.add_widget(Button(text='Save', font_size=40, size_hint_y=None, height=80, on_press=self.updateSettings))

    def updateSettings(self, btn):
        print('this is how i currently save settings, if the user does not click this button and come back to this page'
              ' it looks as though they saved the settings when they really did not')



root_widget = Builder.load_string('''
#:import NoTransition kivy.uix.screenmanager.NoTransition
#:import sys sys
MyScreenManager:
    transition: NoTransition()

    LoginPageScreen:
        ActionBar:
            pos_hint: {'top':1}
        ActionBar:
            pos_hint: {'top':0.07}
            ActionView:
                ActionPrevious:
                    with_previous: False
                ActionOverflow:
                ActionGroup:
                    ActionButton:
                        text: 'Settings'
                        on_release: app.root.current = 'settings'

    UserSettingsScreen:
        ActionBar:
            pos_hint: {'top':1}
        ActionBar:
            pos_hint: {'top':0.07}
            ActionView:
                ActionPrevious:
                    with_previous: True
                    on_release: app.root.current = 'home'


<UserSettingsScreen>:
    name: 'settings'
    # on_pre_enter: userSettingsClass()
    BoxLayout:
        size_hint_y: 0.85
        pos_hint: {'center_y': .5}
        #size_hint: (None, None)
        ScrollView:
            UserSettings
                orientation: 'vertical'
                padding: [50,10,50,10]
                spacing: 10
                # size_hint: (None, None)
                size: (1080, 3000)

<LoginPageScreen>:
    name: 'home'
    BoxLayout:
        LoginPage
            orientation: 'vertical'
            padding: [50,10,50,10]
            spacing: 10
            # size_hint_y: 0.9

''')

class ScreenManagerApp(App):
    def build(self):
        return root_widget

ScreenManagerApp().run()
从kivy.app导入应用
从kivy.lang导入生成器
从kivy.uix.boxlayout导入boxlayout
从kivy.uix.button导入按钮
从kivy.uix.label导入标签
从kivy.uix.screenmanager导入screenmanager,屏幕
从kivy.uix.switch导入开关
从kivy.core.window导入窗口
从kivy.uix.progressbar导入progressbar
从kivy.clock导入时钟
Window.clearcolor=(252235 2330)
#!/usr/bin/python3
类MyScreenManager(屏幕管理器):
通过
类登录页面(屏幕):
通过
类用户设置屏幕(屏幕):
通过
类别登录页面(BoxLayout):
定义初始(自我,**kwargs):
超级(登录页面,自我)。\uuuuu初始化(**kwargs)
self.add\u小部件(标签(text=“[color=000000][b]主页[/b][/color]”,markup=True,size\u-hint\u-y=None,font\u-size='15sp'))
类用户设置(BoxLayout):
定义初始(自我,**kwargs):
超级(用户设置,自我)。\uuuuu初始化(**kwargs)
#self.clear_widgets()
on\u pre\u enter=self.userSettingsClass()
#on_pre_leave=self.userSettingsClass()
def用户设置类(自身):
#self.clear_widgets()
self.add_小部件(标签(text=“[color=000000][b]设置[/b][/color]”,markup=True,font\u size='15sp'))
self.testSwitch=Switch()
self.add_小部件(self.testSwitch)
self.add\u小部件(按钮(text='Save',font\u size=40,size\u hint\u y=None,height=80,on\u press=self.updateSettings))
def更新设置(自身,btn):
print('如果用户未单击此按钮并返回此页面,则这是我当前保存设置的方式'
'看起来他们保存了设置,但实际上没有保存')
root\u widget=Builder.load\u字符串(“”)
#:导入NotTransition kivy.uix.screenmanager.NotTransition
#:导入系统
MyScreenManager:
转换:nottransition()
登录页面:
操作栏:
位置提示:{'top':1}
操作栏:
pos_提示:{'top':0.07}
ActionView:
以前的行动:
与_previous一起:False
ActionOverflow:
行动小组:
操作按钮:
文本:“设置”
发布时:app.root.current='settings'
用户设置屏幕:
操作栏:
位置提示:{'top':1}
操作栏:
pos_提示:{'top':0.07}
ActionView:
以前的行动:
与_previous:True
发布时:app.root.current='home'
:
名称:“设置”
#在\u pre\u输入:userSettingsClass()
盒子布局:
尺寸:0.85
位置提示:{'center_y':.5}
#大小提示:(无,无)
滚动视图:
用户设置
方向:“垂直”
填充:[50,10,50,10]
间距:10
#大小提示:(无,无)
尺寸:(10803000)
:
姓名:“家”
盒子布局:
登录页
方向:“垂直”
填充:[50,10,50,10]
间距:10
#尺寸:0.9
''')
类屏幕管理器RAPP(应用程序):
def生成(自):
返回root\u小部件
ScreenManagerApp().run()
Kivy.uix.settings 首先,看一看,它工作得很好,可以很容易地定制。有关示例,请参见此处的文件夹
6-09-12\u设置
,它是zip文件的一部分。这些都是本书的代码,但我认为代码本身就有很大的帮助。也是

你的解决方案 如果你想坚持你所拥有的,你可以实现类似下面的应用程序。它是应用程序的简化版本,并与按钮状态的全局设置一起使用

从kivy.app导入应用
从kivy.lang导入生成器
从kivy.uix.screenmanager导入screenmanager,屏幕
从kivy.properties导入布尔属性
从kivy.uix.popup导入弹出窗口
开关状态=错误
#!/usr/bin/python3
类MyScreenManager(屏幕管理器):
通过
类别设置屏幕(屏幕):
saved=BooleanProperty()
输入时def更新(自我):
全局开关状态
self.ids.switch.active=开关状态
self.saved=False
def保存(自我):
全局开关状态
开关状态=self.ids.SWITCH.active
self.saved=True
def转换到登录(自我):
打印(自我保存)
全局开关状态
如果未自我保存且未切换\u状态==self.ids.SWITCH.active:
CheckPopup().open()
其他:
self.parent.current='login'
类检查弹出窗口(弹出窗口):
通过
kv_str=Builder.load_字符串(“”)
MyScreenManager:
屏幕:
名称:“登录”
盒子布局:
标签:
文本:“登录”
按钮:
文本:“转到设置”
按:root.current='settings'
设置屏幕:
:
名称:“设置”
on_pre_enter:self.update_on_enter()
盒子布局:
开关:
id:交换机
按钮:
id:savebutton
文本:“保存”
按:root.save()
按钮:
文本:“转到登录”
按:root.transition\u到\u login()
from kivy.app import App
from kivy.lang import Builder

from kivy.uix.screenmanager import ScreenManager, Screen

from kivy.properties import BooleanProperty
from kivy.uix.popup import Popup

SWITCH_STATUS = False

#!/usr/bin/python3

class MyScreenManager(ScreenManager):
    pass

class SettingsScreen(Screen):
    saved = BooleanProperty()
    def update_on_enter(self):
        global SWITCH_STATUS
        self.ids.switch.active = SWITCH_STATUS
        self.saved = False

    def save(self):
        global SWITCH_STATUS
        SWITCH_STATUS = self.ids.switch.active
        self.saved = True

    def transition_to_login(self):
        print(self.saved)
        global SWITCH_STATUS
        if not self.saved and not SWITCH_STATUS==self.ids.switch.active:
            CheckPopup().open()
        else:
            self.parent.current = 'login'


class CheckPopup(Popup):
    pass


kv_str = Builder.load_string('''
MyScreenManager:

    Screen:
        name: 'login'
        BoxLayout:
            Label:
                text: 'login'
            Button:
                text: 'go to Settings'
                on_press: root.current = 'settings'
    SettingsScreen:

<SettingsScreen>:
    name: 'settings'
    on_pre_enter: self.update_on_enter()


    BoxLayout:
        Switch:
            id: switch
        Button:
            id: savebutton
            text: 'save'
            on_press: root.save()
        Button:
            text: 'go to login'
            on_press: root.transition_to_login()

<CheckPopup>:
    title: 'unsaved changes'
    size_hint: None, None
    size: 500, 500 
    BoxLayout:
        Button:
            text: 'discard changes'
            on_press: app.root.current = 'login'; root.dismiss()
        Button:
            text: 'return to Settings'
            on_press: root.dismiss()

''')

class ScreenManagerApp(App):
    def build(self):
        return kv_str

ScreenManagerApp().run()