Не удается добавить мой BoxLayout в ScrollView. Ошибка: «Уже есть родитель» - PullRequest
0 голосов
/ 09 ноября 2019

Я пытаюсь добавить BoxLayout в ScollView, но не могу.

У меня есть ScreenManager (), управляющий двумя экранами: MainScreen () и Songs (), а под песнями у меня есть и BoxLayout (), иScrollView () в init .

Я хочу, чтобы отношения между виджетами были заданы ScreenManager () => Songs (Screen) => ScrollView () => BoxLayout ().

Имейте в виду, что я не могу использовать Builder или a. Файл kv, потому что созданные кнопки являются динамическими.

Кроме того, я оставил все def'ы вне кода для класса Songs, но они у меня есть.

Вот код:


class Mainscreen(Screen):

    def __init__(self, **kwargs):
        super(Mainscreen,self).__init__(**kwargs)
        self.layoutMs = BoxLayout(orientation='vertical')
        self.songButton = Button(text='Songs')
        self.pressed=False
        self.layoutMs.add_widget(Label(text='Welcome To CarsonMusic!'))
        self.songButton.bind(on_press=self.switch_to_songs)
        self.layoutMs.add_widget(self.songButton)
        self.add_widget(self.layoutMs)
    def switch_to_songs(self, *args):
        self.manager.current='song_screen'

class Songs(Screen):#Creates MainScreen class as widget
    titleP = ''
    current_artist=''

    def __init__(self, **kwargs):#Initializes at the beginning whenever mainscreen is called no matter what def
        super(Songs, self).__init__(**kwargs)
        self.Lsong = []#sets default List of song
        self.Lartist = []#sets default List of artists
        self.LsongFil = []#sets default List of files
        self.filebase= os.getcwd()#sets filebase to the original directory DOES NOT NAVIGATE TO MUSIC FOLDER YET
        self.filebaseM = (str(self.filebase)+"/Music/")#Sets filebase of music to music folder in orig directory
        print (self.filebaseM)
        #self.filebaseM2 = filebaseM.replace("/","\\'")
        self.listfil = os.listdir(self.filebaseM)#Gets list of files/folders in Music directory
        self.listfil = [phrase.replace('.mp3', '') for phrase in self.listfil] #removes .mp3 from filename
        self.Lsong=self.listfil#sets new List of songs
        self.song_select_layout = BoxLayout(orientation='vertical')  # Makes layout boxlayout with vertical orientation
        self.song_select_layout.buttons = []  # states that the buttons will be in a list
        self.back_button=Button(text='Back')
        self.back_button.bind(on_press=self.back_to_main)
        self.song_select_layout.add_widget(self.back_button)
        self.np_text=Label(text='Song Playing Now Is')
        self.np_song=Label()
        self.np_Atext=Label(text='By')
        self.np_artist=Label()


        root = ScrollView()
        root.add_widget(self.song_select_layout)
        self.add_widget(root)


        self.curr_art = "Default"
        for song in self.Lsong:  # for loop
            button = Button(text=song, font_size=20, color=(0, 0, 0, 1))  # defines that button is making a button with text of value of song on it
            button.bind(on_press=self.songPlay)  # binds the button to navigate to songPlay method when pressed
            self.song_select_layout.buttons.append(button)  # makes is so that each element of list is appended to a button
            self.song_select_layout.add_widget(button)  # adds the buttons to the layout
        self.add_widget(self.song_select_layout)
        self.song_select_layout.add_widget(self.np_text)
        self.song_select_layout.add_widget(self.np_song)
        self.song_select_layout.add_widget(self.np_Atext)
        self.song_select_layout.add_widget(self.np_artist)

class CarsonMusic(App):
    def build(self):
        sm = ScreenManager()
        main_screen = Mainscreen(name='main_screen')
        song_screen = Songs(name='song_screen')
        sm.add_widget(main_screen)
        sm.add_widget(song_screen)

        return sm

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

Вот ошибка:

 Traceback (most recent call last):
   File "C:/Users/user/Desktop/CarsonMusic/CarsonApp.py", line 170, in <module>
     CarsonMusic().run()
   File "C:\Users\user\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\app.py", line 829, in run
     root = self.build()
   File "C:/Users/user/Desktop/CarsonMusic/CarsonApp.py", line 163, in build
     song_screen = Songs(name='song_screen')
   File "C:/Users/user/Desktop/CarsonMusic/CarsonApp.py", line 78, in __init__
     self.add_widget(self.song_select_layout)
   File "C:\Users\user\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\floatlayout.py", line 140, in add_widget
     return super(FloatLayout, self).add_widget(widget, index, canvas)
   File "C:\Users\user\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\layout.py", line 97, in add_widget
     return super(Layout, self).add_widget(widget, index, canvas)
   File "C:\Users\user\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\widget.py", line 623, in add_widget
     % (widget, parent))
 kivy.uix.widget.WidgetException: Cannot add <kivy.uix.boxlayout.BoxLayout object at 0x040B4D18>, it already has a parent <kivy.uix.scrollview.ScrollView object at 0x0AACE6C0>

Извините за чрезмерное использование слова "self".

1 Ответ

0 голосов
/ 09 ноября 2019

Вы пытаетесь добавить song_select_layout к ScrollView и Songs в методе Songs.__init__():

root.add_widget(self.song_select_layout)

и

self.add_widget(self.song_select_layout)

Youможно только добавить Widget к одному из родителей.

...