[英]How can I access different widget classes in Kivy that are not part of root?
我正在尝试将屏幕添加到屏幕管理器,但是该屏幕是单独的。 这意味着它不是根元素的一部分,而只是一个单独存在的类。 我想在按下图标时将此屏幕添加到屏幕管理器,但是我不知道如何在我的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
可能有一种“更好”的方式来执行此操作,但是现在我们开始。
首先,我必须声明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)
因此,当我尝试切换屏幕时尝试执行相同的操作时,我收到一条错误消息,指出“ ScreenManager仅接受屏幕”。 嗯,那就是我想要做的。 问题是在添加屏幕时,在http://kivy.org/docs/_modules/kivy/uix/screenmanager.html中 ,它必须通过isinstance测试
if not isinstance(screen, Screen):
raise ScreenManagerException(
'ScreenManager accepts only Screen widget.')
而且失败了。
因此,我找到了如何引用另一个类的方法,但是它对此并不起作用。 我希望所有的班级都分开,包括屏幕,所以我只在需要时才叫它们。 为了能够切换到屏幕,像其他两个屏幕一样,我在ScreenManager下添加了屏幕,并且在初始化screenmanager的过程中,我删除了屏幕,希望ID仍然留在屏幕管理器中。 它做到了。 因此,当按下按钮时,我会通过添加一个屏幕并删除其他两个屏幕来给出新屏幕的错觉。 然后,我将实现一个“后退”按钮,以撤消该操作。
<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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.