繁体   English   中英

如何在Kivy中访问不属于root的其他小部件类?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM