在kivy中制作一个切换到不同屏幕的按钮列表视图

Posted

技术标签:

【中文标题】在kivy中制作一个切换到不同屏幕的按钮列表视图【英文标题】:Make a listview of buttons that switch to different screens in kivy 【发布时间】:2014-12-06 15:46:57 【问题描述】:

我的 kivy 项目中还有另一个问题。 我有 50 个屏幕,我想首先显示一个引用屏幕的按钮列表。当按下按钮时,屏幕管理器应该切换到相关屏幕。这是我的代码,但我不知道该怎么办!

来源: https://gist.github.com/daryasary/3a2be816c1f35b748866

from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.app import App
#from kivy.uix.popup import Popup
#from kivy.uix.label import Label
from kivy.core.audio import SoundLoader

Builder.load_string('''
<MenuPage>:
    BoxLayout:
        BoxLayout:
            size_hint:(.1, None)
            Button:
            text: 'Credit'
            #on_press:root.show_popup()
        #ListView:
            #size_hint: .8,.9
            #adapter:
                #sla.SimpleListAdapter(
                #data=["Item #0".format(i) for i in range(100)],
                #cls=button.Button
                #selection_mode='single',
                #allow_empty_selection=False)
        ListView:
            size_hint: .8, .97
            item_strings: [str(index) for index in range(50)]

        BoxLayout:
            size_hint:(.1, None)
            Button:
            text: 'atlas'


<Page>:
BoxLayout:
    BoxLayout:
        size_hint:(.1, None)
        Button:
        text: 'MENU'
        on_press: root.manager.current = 'menu'
    BoxLayout:
        orientation:'vertical'
        Button:
        text:'Title'
        size_hint:(1, .2)
    Image:
        source: '/home/hosein/Pictures/1.png'
        size_hint:(1, .8)
    BoxLayout:
        size_hint:(.1, None)
        Button:
        text: 'atlas'
''')



class MenuPage(Screen):
    M = SoundLoader.load('/home/hosein/Music/Man.mp3')

    def plays(self):
        if MenuPage.M.state == 'stop':
        MenuPage.M.play()
    else:
        MenuPage.M.stop()



class Page(Screen):
    pass



sm = ScreenManager()
menu = MenuPage(name='menu')
sm.add_widget(menu)
for i in range(50):
    name = Page(name=str(i))
    sm.add_widget(name)


class TestApp(App):

    def build(self):
    return sm

if __name__ == '__main__':
    TestApp().run()

【问题讨论】:

到底是什么问题? 我想用 49 个按钮制作可选视图,按每个项目(按钮)屏幕切换管理器指向屏幕。 【参考方案1】:

这 50 个“页面”都是相同的,因此将它们全部替换为一个页面会更有意义,该页面会根据所选菜单按钮更改图片/声音内容。它使用的资源更少,并且更易于调试和维护。

您的资源文件(例如 1.png)也可以通过将它们分组到固定子目录中或使用库提供的间接机制在代码中引用它们来更好地组织 (link)

关于您的问题; listview 机制允许许多不同的方法,但 simpleadapter 是不够的。 ListView 文档 (link) 中提供了很多很好的列表示例

至少,您需要一个列表适配器、一个响应按钮按下的函数,以及该函数与按钮对象的绑定。您可以通过绑定 listadapter.on_selection_change 事件处理程序来做到这一点,但我发现使用特定处理程序创建按钮项类更简洁,这就是我在下面提供的内容。

from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.app import App
from kivy.core.audio import SoundLoader
from kivy.uix.listview import ListItemButton
from kivy.properties import ListProperty, NumericProperty

Builder.load_string('''
#:import la kivy.adapters.listadapter
#:import factory kivy.factory

<MenuButton>:
    size_hint_y: None
    height: dp(24)
    on_release: app.on_menu_selection(self.index)

<MenuPage>:
    BoxLayout:
        BoxLayout:
            size_hint:(.1, None)
            Button:
                text: 'Credit'
                #on_press:root.show_popup()
        ListView:
            size_hint: .8,.9
            adapter:
                la.ListAdapter(
                data=app.data,
                cls=factory.Factory.MenuButton,
                selection_mode='single',
                allow_empty_selection=True,
                args_converter=root.args_converter)

        BoxLayout:
            size_hint:(.1, None)
            Button:
                text: 'atlas'


<Page>:
    BoxLayout:
        BoxLayout:
            size_hint:(.1, None)
            Button:
                text: 'MENU'
                on_press: root.manager.current = 'menu'
        BoxLayout:
            orientation:'vertical'
            Button:
                text:'Title'
                size_hint:(1, .2)
            Image:
                source: '/home/hosein/Pictures/1.png'
                size_hint:(1, .8)
        BoxLayout:
            size_hint:(.1, None)

            Button:
                text: 'atlas'
''')

class MenuButton(ListItemButton):
    index = NumericProperty(0)

class MenuPage(Screen):
    M = SoundLoader.load('/home/hosein/Music/Man.mp3')

    def plays(self):
        if MenuPage.M.state == 'stop':
            MenuPage.M.play()
        else:
            MenuPage.M.stop()

    def args_converter(self, row_index, title):
        print ("0=1".format(row_index, title))

        return 
            'index': row_index,
            'text': title
        

class Page(Screen):
    pass

class TestApp(App):
    data = ListProperty(["Item #0".format(i) for i in range(50)])

    def build(self):
        sm = ScreenManager()
        menu = MenuPage(name='menu')
        sm.add_widget(menu)
        for i in range(50):
            name = Page(name=str(i))
            sm.add_widget(name)
        return sm

    def on_menu_selection(self, index):
        self.root.current = str(index)

if __name__ == '__main__':
    TestApp().run()

【讨论】:

很高兴为您提供帮助。但如果它真的是你要找的,那么请接受答案 它可以工作,但我想将列表视图图标按钮的背景颜色从绿色更改为白色。

以上是关于在kivy中制作一个切换到不同屏幕的按钮列表视图的主要内容,如果未能解决你的问题,请参考以下文章

(Kivy Python)在 .py 文件中按下按钮时切换屏幕

Kivy/ Kivymd 地图切换屏幕

如何在kivy中居中按钮?

Kivy - 通过引用根属性动态添加按钮

在 Kivy 中制作(继续)选项屏幕

如何使用 python 代码在 Kivy 中切换屏幕