How can one object instance stop sound that other instance is playing?
我对编程有些陌生。我正在使用Kivy框架构建一个简单的应用程序。这个应用程序有15个按钮。当你按下按钮,它开始播放一段旋律。如果此时正在播放任何其他按钮,则该按钮应停止,即不应同时播放多个声音(来自不同实例)。
这就是我所做的-我创建了一个处理停止和播放声音的类方法。按下时,按钮实例将声音对象传递给这个类方法。然而,第一次按下,由于声音对象还不存在,我的应用程序崩溃。因此,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | class Gumb(Button): soundfile = StringProperty(None) sound = ObjectProperty(None) now_playing_object = None def on_soundfile(self, instance, value): self.sound = SoundLoader.load(value) def on_press(self): if self.sound: self.__class__.play_sound(self.sound) @classmethod def play_sound(cls, new_sound_object): try: if cls.now_playing_object.state != 'stop': cls.now_playing_object.stop() except AttributeError: pass cls.now_playing_object = new_sound_object cls.now_playing_object.play() |
但我不喜欢这个,尤其是the
谢谢!
更新1:@托托·提科为我提供了一些解决方案,以避开
使用
1 2 | if cls.now_playing_object != None and cls.now_playing_object.state != 'stop': cls.now_playing_object.stop() |
尽管,在阅读了关于Python的IFS和异常的效率之后,我不确定是否应该尝试消除
从一开始就初始化
1 | now_playing_object = SoundLoader.load(‘non_existant_file.wav’) |
这是可行的,但感觉有点不可靠(奇怪的是,如果文件名缺少扩展名,Kivy会抱怨,但如果根本没有文件,就不会抱怨)。不过,我想我还是要用这个。
更新2:
结果发现解决方案就在我面前。我就是看不见。确实不需要
1 2 3 4 5 6 7 | class Gumb(Button): ... def play_sound(self): if self.__class__.now_playing_object.state is not 'stop': self.__class__.now_playing_object.stop() self.__class__.now_playing_object = self.sound self.__class__.now_playing_object.play() |
我已经接受了答案,但真正的答案是在评论中。多谢@toto'u tico。
你只要检查一下
而不是:
1 2 3 4 5 6 | try: if cls.now_playing_object.state != 'stop': cls.now_playing_object.stop() except AttributeError: pass ... |
您应该能够做到:
1 2 3 | if cls.now_playing_object != None and cls.now_playing_object.state != 'stop': cls.now_playing_object.stop() ... |
希望它有帮助。
要取出if条件:
如果不想检查,那么应该从一开始就初始化变量。我不知道您用于
而不是:
1 | now_playing_object = None |
您应该用以下方法初始化它:
1 2 | #maybe needs parameters or simple use now_playing_object = ObjectProperty(None) now_playing_object = Sound() |
然后你可以去掉我第一个答案(
取出
我发现你在使用
如果(1)您只有一个
现在,如果您希望15个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | class Gumb(Button): # Constructor. def __init__(self, **kwargs): super(Gump, self).__init__(**kwargs) #This became attributes of the self.soundfile = StringProperty(None)\ self.sound = ObjectProperty(None) self.now_playing_object = ObjectProperty(None) def on_soundfile(self, instance, value): self.sound = SoundLoader.load(value) def on_press(self): if self.sound: self.play_sound() def play_sound(self): if self.now_playing_object.state != 'stop': self.now_playing_object.stop() # self.sound was your new_playing_object, since it is part of the instance # you don't need to send it as parameter self.now_playing_object = self.sound self.now_playing_object.play() |
这更像你想要的吗?