【问题标题】:Python Kivy Screen InheritancePython Kivy 屏幕继承
【发布时间】:2016-05-12 17:38:50
【问题描述】:

背景:我只使用 Python 来实现 Kivy 屏幕。我有两个屏幕,它们都包含一个列表和两行按钮。我认为创建一个具有这些布局的屏幕类,然后使用继承来创建两个屏幕并根据需要向布局添加按钮是一种很好的编程实践。

问题:但是,当我这样做时,我发现在子屏幕中我无法访问 self.manager.current

问题:有人知道它为什么或如何不继承父屏幕的管理器属性吗?

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.listview import ListView, ListItemButton
from kivy.adapters import listadapter
from kivy.uix.button import Button
from kivy.properties import ListProperty, StringProperty
from kivy.uix.screenmanager import ScreenManager, Screen, SlideTransition


class ListScreen(Screen): # This is the super class that I am trying to inherit through
    itemList = ListProperty([])
    selected_value = StringProperty()
    layout = BoxLayout(orientation ='vertical')
    top_buttons=BoxLayout(size_hint_y=0.1)
    scrollable_list=ListView(adapter=listadapter, size_hint_y=0.8)
    scrollable_list.data=itemList
    scrollable_list.selection_mode='single'
    scrollable_list.allow_empty_selection=False
    # scrollable_list.cls=ListItemButton <-- Unrelated bug here, ignore this line
    bot_buttons=BoxLayout(size_hint_y=0.1)

    def __init__(self, **kwargs):
        super(ListScreen, self).__init__(**kwargs)

    def finalize_widgets(self):
        self.layout.add_widget(self.top_buttons)
        self.layout.add_widget(self.scrollable_list)
        self.layout.add_widget(self.bot_buttons)
        self.add_widget(self.layout)

    def change(self,change):
        self.selected_value = 'Selected: {}'.format(change.text)

    def change_screen(self, screen_name):
        self.manager.current = screen_name # <-- Here is the problem


class SubScreen(ListScreen):
# This is one of the child classes, intended to inherit Screen through the parent ListScreen class.

    def __init__(self, **kwargs):
        super(SubScreen, self).__init__(**kwargs)

        save = Button(text='Save')
        load = Button(text='Load')
        new_d = Button(text='New')
        new_s = Button(text='New Search')

        self.top_buttons.add_widget(save)
        self.top_buttons.add_widget(load)
        self.top_buttons.add_widget(new_d)
        self.top_buttons.add_widget(new_s)

        new_s.bind(on_press = self.change_screen('search'))


class ListBuilderApp(App):
    def build(self):
        sm = ScreenManager(transition=SlideTransition())
        sm.add_widget(SubScreen(name='list'))
        sm.add_widget(SearchResults(name='results'))
        sm.add_widget(SearchScreen(name='search'))
        return sm

if __name__ == "__main__":
    ListBuilderApp().run()

【问题讨论】:

    标签: android python inheritance screen kivy


    【解决方案1】:

    好吧,我看不到ScreenManager,这基本上是您使用self.manager(object) 得到的,所以...

    没有ScreenManager,在python或kv之类的小部件中添加了屏幕(add_widget()),在任何Screens中都没有self.manager - 你无法访问不存在的东西。

    添加一些将成为屏幕根的类,并将其设为ScreenManager + 将屏幕添加为子级。

    编辑: 我可能是盲人,但我没有看到on_press=.. 的东西。存在问题,因为您没有将函数分配给事件,而是在将('search') 放在末尾时调用该函数。 (尝试做self.parent 你会看到)

    Kivy 事件(至少“on_”)捕获函数,但不捕获参数,不直接捕获。这就是为什么你需要使用partial

    from functools import partial
    new_s.bind(on_press = partial(self.change_screen,'search'))
    

    这样,错误就消失了,但是一些适配器绑定跳了出来,我真的不知道如何修复,因为我不经常使用它。

    【讨论】:

    • 非常抱歉,我确实有这门课,我已经编辑了问题以包含该课程。它仍然存在与问题中所述相同的问题。
    • 谢谢!我会花一些时间来解决这个问题。当我使用 add_widget() 将它们添加到 sm 时,我还能够通过将 manager=sm 放入屏幕的参数中来部分解决问题。您认为将管理器类中的屏幕制作为具有不同名称的 ListScreen() 的两个副本,然后在其中添加按钮会更好吗?
    • 从头开始,重新设置管理器不起作用,我不应该尝试 XD 我尝试使用部分,我明白你对适配器绑定的意思。我想我只是要创建两个包含相似代码的单独屏幕类,无论我尝试什么,继承似乎都不能正常工作。
    猜你喜欢
    • 2018-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多