Reputation: 29
Me again, here is my code, why is "beep.wav" playing when I launch the application rather than when I press the buttons I assume I have bound it to?
import kivy
import random
from kivy.core.audio import SoundLoader
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
sound = SoundLoader.load('beep.wav')
red = [1,0,0,1]
green = [0,1,0,1]
blue = [0,0,1,1]
purple = [1,0,1,1]
class A_Cool_Program(App):
def Orientation(self, orient):
self.orient = orient
def build(self):
layout = BoxLayout(padding=0, orientation=self.orient)
colors = [red, green, blue, purple]
for i in range(5):
btn = Button(text="Test Button %s" % (i+1), background_color=random.choice(colors))
layout.add_widget(btn)
sound = SoundLoader.load('beep.wav')
btn.bind(on_press=sound.play())
return layout
if __name__ == "__main__":
app = A_Cool_Program()
app.Orientation(orient="vertical")
app.run()
Upvotes: 0
Views: 766
Reputation: 29460
btn.bind(on_press=sound.play())
This line calls the function, just as you should always expect when you use the function call syntax - you called sound.play()
, therefore the function is called and you hear the sound. The bind
method doesn't know about any of this, it only sees the return value of the function, which is probably just None
.
I think in this case you want instead something like
btn.bind(on_press=lambda *args: sound.play())
This passes in a lambda function, and when that function is called then sound.play()
is run. This example is actually unusual because sound.play
doesn't seem to accept any arguments, but kivy bindings automatically pass at least the instance of the button, so this code uses a lambda function to eat that argument.
You normally could just do:
def some_function(*args):
print('the button was pressed!')
...
btn.bind(on_press=some_function)
Note the lack of brackets to actually call some_function
. It will be called later when the button is pressed.
Upvotes: 3