我在Kivy gui应用程序中有一个嵌套的屏幕管理器,它们都可以加载下一个和上一个屏幕,并且它们绝对可以正常工作。
我有一个按钮,它可以重新加载每个屏幕,并且不重复操作,我必须先移除所有屏幕,然后再调用该功能,以重建其中的所有屏幕和小部件。
但是每当我执行某些操作时,屏幕都不会删除。在所有当前屏幕名称print(self.screen_names)
的帮助下,我每次按下按钮都可以看到屏幕上发生了什么。
未按下按钮screen_names
时:
['Screen 1', 'Screen 2', 'Screen 3', 'Screen 4']
在我按下按钮screen_names
之后:
['Screen 2', 'Screen 4', 'Screen 1', 'Screen 2', 'Screen 3', 'Screen 4']
第二次按下screen_names
:
['Screen 4', 'Screen 2', 'Screen 4', 'Screen 1', 'Screen 2', 'Screen 3', 'Screen 4']
第三次推送screen_names
:
['Screen 2', 'Screen 1', 'Screen 3', 'Screen 1', 'Screen 2', 'Screen 3', 'Screen 4']
第三次按下后,我总是得到以下输出:
['Screen 1', 'Screen 1', 'Screen 3', 'Screen 1', 'Screen 2', 'Screen 3', 'Screen 4']
会重复自身
切换屏幕变得混乱,因为管理者没有将屏幕切换到女巫。
py:
class Manager(ScreenManager):
def __init__(self, **kwargs):
super(Manager, self).__init__(**kwargs)
Clock.schedule_once(self.pst_nt, 0)
def refresh(self):
print(self.screen_names)
self.pst_nt(None)
self.current = 'Screen 1'
def next_s(self):
self.current = self.next()
self.transition.direction = 'left'
def previous_s(self):
self.current = self.previous()
self.transition.direction = 'right'
def pst_nt(self, dt):
self.clear_widgets()
dn.load()
screen_number = 0
for k, v in dn.DND.items():
screen_number += 1
print(screen_number)
self.bxlt = BoxLayout(size_hint=(1, .1),
我尝试了remove_widget()
,但出现了一个完全不同的错误。
Edit1:一个最小的可运行示例:
from kivy.app import App
from kivy.clock import Clock
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen
Dict = {'rand1': 1, 'rand2':2, 'rand3':3}
class Manager(ScreenManager):
def __init__(self, **kwargs):
super(Manager, self).__init__(**kwargs)
Clock.schedule_once(self.pst_nt, 0)
def refresh(self):
print(self.screen_names)
self.pst_nt(None)
self.current = 'Screen 1'
def next_s(self):
self.current = self.next()
self.transition.direction = 'left'
def previous_s(self):
self.current = self.previous()
self.transition.direction = 'right'
def pst_nt(self, dt):
self.clear_widgets()
#dn.load() # this is needed for my project
screen_number = 0
for k, v in Dict.items():
screen_number += 1
self.mainlbl = Label(text='{} {}'.format(screen_number, str(k)),
font_size='13sp',
size_hint=(.5, 1))
self.refbtn = Button(text='Refresh',
size_hint=(1, .3),
on_release=lambda x: self.refresh())
self.next_btn = Button(text='Next',
size_hint=(1, .2),
on_release=lambda x: self.next_s())
self.back_btn = Button(text='Back',
size_hint=(1, .2),
on_release=lambda x: self.previous_s())
self.bxlt = BoxLayout(orientation= 'vertical',size_hint=(1, 1))
self.bxlt.add_widget(self.mainlbl)
self.bxlt.add_widget(self.refbtn)
self.bxlt.add_widget(self.next_btn)
self.bxlt.add_widget(self.back_btn)
self.scrn = Screen(name='Screen {}'.format(screen_number))
self.scrn.add_widget(self.bxlt)
self.add_widget(self.scrn)
class TestApp(App):
def build(self):
return Manager()
if __name__ == '__main__':
TestApp().run()
因此在此示例中,在按下刷新按钮后,无法加载某些屏幕。
答案 0 :(得分:1)
您已经发现Kivy中的一个错误,ScreenManager.clear_widgets
不能正确地遍历屏幕。
我创建了一个拉取请求来修复此here。它应该包含在下一个Kivy版本中。
同时,您可以通过将clear_widgets覆盖到ScreenManager子类中来解决此问题:
def clear_widgets(self, screens=None):
if screens is None:
screens = self.screens
for screen in screens[:]:
self.remove_widget(screen)
这与我在上面介绍的修复程序相同。