I got an error from this code, I am trying to change the color of the button when pressed.
The code:
Builder.load_string('''
<FileBrowserApp>:
Button:
id: 'b1'
text: 'Select Files'
pos_hint: {'x':0, 'y': 0}
size_hint: (1, 0.1)
on_press: self.do_select
on_press: self.background_color=[0,0,255,1]
on_release: self.background_color=[192,192,19,1]
''')
class FileBrowserApp(App):
def build(self):
try:
if(self.out):
self.root.remove_widget(self.out)
except:
pass
self.root = FloatLayout()
self.bn = BoxLayout(orientation="horizontal")
button1 = self.ids['b1']
self.bn.add_widget(button1)
self.out = BoxLayout(orientation="vertical")
self.root.add_widget(self.out)
self.root.add_widget(self.bn)
return self.root
The error:
Traceback (most recent call last):
File "kk.py", line 120, in <module>
app.run()
File "/usr/lib/python3/dist-packages/kivy/app.py", line 800, in run
root = self.build()
File "kk.py", line 47, in build
button1 = self.ids['b1']
AttributeError: 'FileBrowserApp' object has no attribute 'ids'
is that Builder.load_string() allows more than one class to create a kv language
How to resolve this error?
You cannot add a Button
to the FileBrowserApp
as you appear to attempt in your kv
. Your construction is appropriate for adding a Button
to a container (like a Layout
), but an App
is not a container. If you want to define a Button
in your kv
you can do it by defining a new class that extends Button
like this:
class SelectFileButton(Button):
pass
Then create a rule for SelectFileButton
in the kv
:
Builder.load_string('''
<SelectFileButton>:
text: 'Select Files'
pos_hint: {'x':0, 'y': 0}
size_hint: (1, 0.1)
on_press: app.do_select()
on_press: self.background_color=[0,0,255,1]
on_release: self.background_color=[192,192,19,1]
''')
This rule defines how a SelectFileButton
should be configured, and can then be used in the build()
method:
class FileBrowserApp(App):
def build(self):
try:
if (self.out):
self.root.remove_widget(self.out)
except:
pass
self.root = FloatLayout()
self.bn = BoxLayout(orientation="horizontal")
# create a Button based on the kv rule
button1 = SelectFileButton()
self.bn.add_widget(button1)
self.out = BoxLayout(orientation="vertical")
self.root.add_widget(self.out)
self.root.add_widget(self.bn)
return self.root
def do_select(self):
print('do select')
That is one way to do it, but a better approach might be to create a rule in kv
that describes how the entire root of the FileBrowserApp
should be built. Then the build()
method would simply be returning that root. Or, if you put that kv
in a file named filebrowser.kv
, you don't even need a build()
method. See the documentation.