我正在尝试将屏幕添加到屏幕管理器,但该屏幕是独立的。这意味着它不是根元素的一部分,只是一个独立的类。我想在按下图标时将此屏幕添加到屏幕管理器,但我无法弄清楚如何在我的kv文件中引用屏幕。
我猜你一般如何引用kv lang中不属于根小部件的小部件(属于一个单独的类)?
usb_screen_manager.kv
#:import label kivy.uix.label
#:import sla kivy.adapters.simplelistadapter
#:import hvt hub_validation_test
<UsbScreenManager>:
id: manager
H2HScreen:
HubValidationScreen:
<H2HScreen>:
id: h2h
name: 'h2h'
BoxLayout:
id:bl
orientation: 'vertical'
TestIcon:
id: h2hicon
source: 'h2h.png'
<HubValidationScreen>:
id: hvs
name: 'hvs'
BoxLayout:
id:bl
orientation: 'vertical'
TestIcon:
id: hubvicon
source: 'usb_button.png'
on_touch_down: app.root.manager.switch_to(hvts) <--add screen when this icon is pressed
Label:
text: 'Hub Validation test'
size_hint: (1,.25)
<HubValidationTestScreen>:
id: hvts
name: 'hvts'
BoxLayout:
ListView:
adapter:
sla.SimpleListAdapter(
data= hvt.requirements,
cls= label.Label)
sam1.kv(包含根元素的kv文件)
<MainPanel>:
id: mp
manager: manager
size_hint: 1,1
tab_width: 65
do_default_tab: False
tab_pos: 'top_right'
TabbedPanelItem:
id: usb_tab
text: 'Usb'
BoxLayout:
orientation: 'vertical'
UsbScreenManager:
id: manager
NavLayout:
id: nav
TabbedPanelItem:
id: remote_tab
text: 'Remote'
TabbedPanelItem:
id: sd_tab
text: 'SD'
<NavLayout>:
id: nav
spacing: 5,5
rows: 1
size_hint: 1, .2
LeftButton:
id: left_arrow_button
on_release: app.root.manager.current = app.root.manager.previous()
Image:
source: 'left_arrow_iconb.png'
center: left_arrow_button.center
size: nav.width*.8, nav.height*.8
BackButton:
id: back_button
Image:
source: 'back_iconb.png'
center: back_button.center
size: nav.width*.8, nav.height*.8
RightButton:
id: right_arrow_button
on_release: app.root.manager.current = app.root.manager.next()
Image:
source: 'right_arrow_iconb.png'
center: right_arrow_button.center
size: nav.width*.8, nav.height*.8
答案 0 :(得分:2)
可能有更好的&#34;这样做的方式,但我们走了。
首先,我必须声明Kivy Properties,在这个例子中是ObjectProperty(),可能不像它们看起来那样。正如文档所述,ObjectProperty可能表示一个python对象,但让它知道它不会是实际的对象。当ObjectProperty必须通过isinstance测试时,这很重要,因为它会失败。
我提到这个是因为当我不得不从Kivy的另一个类引用我的ListViewLabel类时,我认为我已经解决了我的问题。 (我创建了一个ListViewLabel类来正确格式化我将在屏幕上显示的列表)。我使用ObjectProperty做到了这一点,它就像一个魅力。
in main.py
class HubValidationTestScreen(Screen):
lvl = ObjectProperty(ListViewLabel)
#manager = ObjectProperty(UsbScreenManager)
pass
in kv file
<HubValidationTestScreen>:
id: hvts
name: 'hvts'
BoxLayout:
ListView:
adapter:
sla.SimpleListAdapter(
data= hvt.requirements,
cls= root.lvl) <---I'm a genius! (not really)
因此,当我尝试切换屏幕时尝试相同的操作时,我收到了一个错误,指出“屏幕管理器只接受屏幕&#39;”。嗯,这就是我想做的事情。问题在于http://kivy.org/docs/_modules/kivy/uix/screenmanager.html在添加屏幕时必须通过isinstance测试
if not isinstance(screen, Screen):
raise ScreenManagerException(
'ScreenManager accepts only Screen widget.')
它失败了。
所以我发现了如何引用另一个类,但它不适用于此。 我希望我的所有课程都是独立的,包括屏幕,所以我只是在需要时给他们打电话。所以为了能够切换到我所做的屏幕,我的屏幕管理器下的屏幕就像其他两个一样,并且在屏幕管理器的初始化期间我移除了屏幕,希望id仍然留在屏幕管理器中。它确实如此。因此,当按下按钮时,我通过添加一个屏幕并移除另外两个屏幕来给出新屏幕的错觉。然后,我将实施一个&#39; back&#39;按钮可以反转此动作。
<UsbScreenManager>:
id: manager
hvts:hvts
h2h: h2h
H2HScreen:
id:h2h
HubValidationScreen:
id:hvs
HubValidationTestScreen:
id: hvts
class UsbScreenManager(ScreenManager):
hvts = ObjectProperty()
h2h = ObjectProperty()
def __init__(self, **kwargs):
Clock.schedule_once(self.remove, .5)
print(str(self.ids))
super(UsbScreenManager, self).__init__(**kwargs)
def remove(self, b):
self.remove_widget(self.hvts)
pass
<HubValidationScreen>:
id: hvs
name: 'hvs'
BoxLayout:
id:bl
orientation: 'vertical'
TestIcon:
id: hubvicon
source: 'usb_button.png'
on_press: hvs.manager.switch_to(app.root.manager.hvts); app.root.manager.remove_widget(app.root.manager.h2h)