0

我正在使用 python 和 tkinter 编写一个音乐数据库管理器。它几乎全部完成,但我坚持播放列表中的歌曲。原生 macOS 播放器 NSSound 有一个内置回调到一个委托,它发出轨道结束的信号,所以我想用它来触发一个虚拟事件回到主应用程序以发送下一首歌曲播放。但我不知道如何使回调工作,并希望得到一些帮助(这只是一个有点失控的爱好项目)。

此框架代码显示了应用程序的相关结构并按预期播放选定的文件,但我多次尝试制定委托都没有奏效。据我了解,播放器指定 Delegate 类作为其委托,然后这个类应该有一个回调方法“声音”以在歌曲结束时接收消息。我试图从 Apple Developer协议中找出它,并且还进行了广泛的搜索,只找到了一个示例

我如何才能获得“成功!” 请留言?

from AppKit import NSSound
import tkinter as tk
from tkinter import filedialog
       
class Delegate (NSSound):
    def init(self):
        self = super(Delegate, self).init()
        return self        
    #def sound (...) ???   #this should fire when the song finishes?
    #   print('Success!')
    
class App(tk.Tk):  #representing the rest of the music database app
    def __init__(self):
        super().__init__()         
        file = filedialog.askopenfilename()          
        song = NSSound.alloc()
        song.initWithContentsOfFile_byReference_(file, True) 
        delegate = Delegate.alloc().init()
        song.setDelegate_(delegate)      
        song.play()
           
if __name__ == "__main__":
    app = App()
    app.mainloop()
  
4

2 回答 2

0

感谢您的帮助@valeCocoa,您的坚持帮助很大。这有效:

from AppKit import NSSound
import tkinter as tk
from tkinter import filedialog
import objc

class Song (NSSound) : 
    def initWithFile_(self, file): 
        self = objc.super(Song, self).initWithContentsOfFile_byReference_(file, True) 
        if self is None: return None
        self.setDelegate_(self)
        return self    
    def sound_didFinishPlaying_(self, _, didFinish):
        print('Success')

class App(tk.Tk):  #representing the rest of the music database app
    def __init__(self):
        super().__init__()         
        file = filedialog.askopenfilename()          
        song = Song.alloc().initWithFile_(file)
        song.play()

if __name__ == "__main__":
    app = App()
    app.mainloop()
于 2021-11-15T22:11:30.197 回答
0

NSSound实例将在其上调用具有此(swift)签名的方法delegate

sound(_:didFinishPlaying:)

因此,我认为您的 Python 函数应该具有相同的签名:它的名称应该是sound并且它应该接受两个参数,第一个参数没有 type 的标签 (_) NSSound,第二个参数的 typeBool有 label didFinishPlaying

sound的委托中的函数似乎没有这样的签名,因此很可能它没有被调用。

这是因为委托上的此类方法是可选的,这意味着如果符合的实例NSSoundDelegate未实现此类方法,则在委托实例尝试使用时不会陷入陷阱NSSound

于 2021-11-13T01:23:52.260 回答