I am trying to add BoxLayout to ScollView but I can't.
I have a ScreenManager() managing two screens: MainScreen() and Songs() and under songs I have both BoxLayout() and ScrollView() under init.
I want the relationship between widgets go ScreenManager() => Songs(Screen) => ScrollView() => BoxLayout().
Keep in mind that I cannot use Builder or a .kv file because buttons created are dynamic.
Also, I left all the 'def's out of the code for the Songs class but I have them.
Here is the code:
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()
Here is the error:
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>
Sorry for my over-usage of 'self.'
You are trying to add the song_select_layout
to both the ScrollView
and the Songs
in the Songs.__init__()
method:
root.add_widget(self.song_select_layout)
and
self.add_widget(self.song_select_layout)
You can only add a Widget
to one parent.