在macOS上使用PyObjC注册MPEG-4为拖拽类型遇阻
解决PyObjC拖拽语音备忘录MPEG-4文件的报错问题
你遇到的“无法打开文档”错误,本质是系统默认的文件打开行为被触发了——当你把文件拖到应用窗口时,macOS会尝试让应用打开该文件,但你的Python程序没处理这个默认流程,所以弹出错误提示。以下是修复方案:
关键修复点
- 阻止系统默认的文件打开提示:在AppDelegate中实现
applicationOpenFiles_方法,拦截系统的默认打开请求。 - 正确解析拖拽的文件URL:在
performDragOperation_中从粘贴板提取实际的文件路径,而不是仅打印粘贴板对象。 - 补充正确的UTI类型:语音备忘录导出的.m4a文件对应的UTI是
public.mpeg-4-audio,补充public.mpeg-4可确保覆盖所有相关类型。
修改后的完整代码
from AppKit import ( NSApplication, NSObject, NSDragOperationCopy, NSWindow, NSView, NSPasteboard, NSURL ) from PyObjCTools import AppHelper class DropView(NSView): def initWithFrame_(self, frame): self = super(DropView, self).initWithFrame_(frame) if self: # 注册需要的拖拽类型,补充public.mpeg-4确保覆盖 self.registerForDraggedTypes_([ "public.audio", "public.mpeg-4-audio", "public.mpeg-4", NSPasteboard.URLType, NSPasteboard.fileURLType ]) return self def draggingEntered_(self, sender): # 验证粘贴板是否包含我们需要的类型 pboard = sender.draggingPasteboard() if pboard.availableTypeFromArray_(self.registeredDraggedTypes()): return NSDragOperationCopy return NSDragOperationNone def performDragOperation_(self, sender): pboard = sender.draggingPasteboard() # 尝试从粘贴板获取文件URL file_url = pboard.readObjectForType_(NSPasteboard.fileURLType) if file_url: file_path = file_url.path() print(f"拖拽的文件路径:{file_path}") # 这里添加你处理文件的逻辑 return True return False class AppDelegate(NSObject): def applicationDidFinishLaunching_(self, notification): self.window = NSWindow.alloc().initWithContentRect_styleMask_backing_defer_( ((100, 100), (400, 300)), 1 << 1 | 1 << 10 | 1 << 2, # 补充关闭、最小化按钮样式 2, False ) self.window.setTitle_("语音备忘录拖拽测试") drop_view = DropView.alloc().initWithFrame_(((0, 0), (400, 300))) self.window.contentView().addSubview_(drop_view) self.window.makeKeyAndOrderFront_(None) def applicationOpenFiles_(self, sender, filenames): # 拦截系统默认的文件打开请求,避免弹出错误提示 return def run_app(): app = NSApplication.sharedApplication() delegate = AppDelegate.alloc().init() app.setDelegate_(delegate) AppHelper.runEventLoop() if __name__ == '__main__': run_app()
代码说明
applicationOpenFiles_方法:系统尝试让应用打开文件时会调用这个方法,空实现它就能阻止错误提示弹出。draggingEntered_优化:增加类型验证,只有粘贴板包含注册类型时才允许拖拽操作,避免无效拖拽。performDragOperation_完善:从粘贴板读取fileURLType数据并转换为文件路径,这样就能获取拖拽文件的实际位置,后续可添加自定义处理逻辑。- 补充UTI类型:添加
public.mpeg-4,确保覆盖语音备忘录文件的所有关联UTI类型,避免遗漏。
内容的提问来源于stack exchange,提问作者cwiz
相关产品推荐
相关产品推荐

