多个屏幕但 self.root.id 返回错误

Posted

技术标签:

【中文标题】多个屏幕但 self.root.id 返回错误【英文标题】:Multiple screens but self.root.ids retuns an error 【发布时间】:2021-06-16 21:52:24 【问题描述】:

在我添加多个屏幕之前,这段代码实际上是有效的。当我删除多屏幕管理器时它仍然有效。我将属性错误点指向Chapter ids 我正在尝试添加章节屏幕。请问我做错了什么。

我认为错误来自 self.root.ids。我可能错了。下面是代码

Python

from kivymd.app import MDApp
from kivymd.uix.list import OneLineListItem
from kivy.uix.screenmanager import ScreenManager, Screen
from kivymd.uix.button import MDRectangleFlatIconButton, MDFloatingActionButton
from kivy.lang import Builder
import pygame

pygame.mixer.init()
path = "C://abapp3"


class BooksScreen(Screen):
    pass


class ChapterScreen(Screen):
    pass


class MainApp(MDApp):
    def build(self):
        sm = ScreenManager()
        sm.add_widget(BooksScreen(name='BooksScreen1'))
        sm.add_widget(ChapterScreen(name='ChapterScreen1'))

    return sm

def on_start(self):
    songs = self.load_songs(path)
    pygame.mixer.music.load(songs[0])

def load_songs(self, path_):
    songs = []
    for filename in os.listdir(path_):
        if filename.endswith('.wav'):
            songs.append(os.path.join(path_, filename))
            self.root.ids.Chapter.add_widget(OneLineListItem(text=filename[2:],
                                                         on_release=self.play_song,
                                                         pos_hint="center_x": 1, "center_y": 1, ))

    return songs

@staticmethod
def play_song(*args):
    pygame.mixer.music.play()
    print(OneLineListItem.text)

@staticmethod
def stop_song(*args):
    pygame.mixer.music.stop()
    print("song stopped")

MainApp().run()

.KV

ScreenManager:
    Screen
        BooksScreen:
        ChapterScreen:



<BooksScreen>:
    NavigationLayout:
        ScreenManager:
            Screen:
                # Front / Main Screen
                MDBoxLayout:
                    orientation: "vertical"
                   #Toolbar
                    MDToolbar:
                        title: "Chapters"
                        font_style: "Caption"
                        elevation: 8
                        left_action_items: [['menu', lambda x: nav_drawer.set_state("open")]]

                    Widget:

                #stop/pause Button
                MDBoxLayout:
                    orientation:"vertical"
                #    id: StopButton
                    text:"Pause"

                BoxLayout:
                    Button:
                        text: 'Goto settings'
                        on_press:
                            root.manager.transition.direction = 'left'
                            root.manager.current = 'ChapterScreen1'





                # Chapters list/ Play list
                MDScreen
                    MDBoxLayout:
                        orientation: "vertical"
                        MDList
                            id: Chapter



        #Options menu
        MDNavigationDrawer:
            id: nav_drawer
            MDBoxLayout:
                orientation: "vertical"
                padding: "8dp"
                spacing: "8dp"




                ScrollView:
                    # Options Menu Options
                    MDList:
                        MDRectangleFlatIconButton:
                            on_press:
                                root.ids.nav_drawer.set_state("close")

                            pos_hint: "center_x": .5, "center_y": .5
                            icon: 'arrow-left'
                            line_color: 0, 0, 0, 0




                        OneLineIconListItem:
                            text: "Options"
                            font_style: "Caption"
                            #size_hint_y: None
                            #height: self.texture_size[1]

                         # Options Menu- About
                        OneLineIconListItem:
                            text: "About"
                            font_style: "Caption"
                           # size_hint_y: None
                            #height: self.texture_size[1]

                        # Options Menu Storage
                        OneLineIconListItem
                            text: 'Storage'
                            font_style: "Caption"
                            #IconLeftWidget
                                #icon: 'tools'

                        # Options Menu Toolbox
                        OneLineIconListItem:
                            text: 'Choose Voice'
                            font_style: "Caption"

                            #IconLeftWidget:
                            #    icon: 'toolbox'

                        # Options Menu About
                        OneLineIconListItem:
                            text: 'About'
                            font_style: "Caption"
                           # IconLeftWidget:
                            #    icon: 'toolbox-outline'
<ChapterScreen>:
    BoxLayout:
        Button:
            text: 'Back to menu'
            on_press:
                root.manager.transition.direction = 'right'
                root.manager.current = 'BooksScreen1'

【问题讨论】:

【参考方案1】:

行:

        self.root.ids.Chapter.add_widget(OneLineListItem(text=filename[2:],
                                                     on_release=self.play_song,
                                                     pos_hint="center_x": 1, "center_y": 1, ))

正在尝试引用 Chapter id,就好像它是 ScreenManager (root) ids 的成员一样,但事实并非如此。它是BookScreenids 的成员。您可以通过使用ScreenManagerget_screen() 方法在问题行中引用BookScreen 实例来修复该错误:

        self.root.get_screen('BooksScreen1').ids.Chapter.add_widget(OneLineListItem(text=filename[2:],
                                                     on_release=self.play_song,
                                                     pos_hint="center_x": 1, "center_y": 1, ))

【讨论】:

以上是关于多个屏幕但 self.root.id 返回错误的主要内容,如果未能解决你的问题,请参考以下文章

使用谷歌地图的两个屏幕返回应用程序的问题

具有多个 collectionView 控制器的 iOS 屏幕错误地调用 cellForItemAtIndexPath

需要一个在 Android 上处理大屏幕和小屏幕的工作示例

getBoundingClientRect 返回错误的结果

使用 HttpWebRequest.GetResponse() 进行屏幕抓取时出现错误“远程服务器返回错误:(403) Forbidden”

kivy 按钮按下以转到多个屏幕之一