You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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()

代码说明

  1. applicationOpenFiles_方法:系统尝试让应用打开文件时会调用这个方法,空实现它就能阻止错误提示弹出。
  2. draggingEntered_优化:增加类型验证,只有粘贴板包含注册类型时才允许拖拽操作,避免无效拖拽。
  3. performDragOperation_完善:从粘贴板读取fileURLType数据并转换为文件路径,这样就能获取拖拽文件的实际位置,后续可添加自定义处理逻辑。
  4. 补充UTI类型:添加public.mpeg-4,确保覆盖语音备忘录文件的所有关联UTI类型,避免遗漏。

内容的提问来源于stack exchange,提问作者cwiz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 16:32:48