10.6中PyObjC中的openPanelDidEnd问题

时间:2010-09-28 02:48:13

标签: python objective-c macos pyobjc

以下在OS X 10.5下运行良好的代码现在在10.6上失败了:

    @IBAction
def addButton_(self, sender):
    panel = NSOpenPanel.openPanel()
    panel.setCanChooseDirectories_(YES)
    panel.setAllowsMultipleSelection_(YES)
    try:
        panel.beginSheetForDirectory_file_modalForWindow_modalDelegate_didEndSelector_contextInfo_(self.directory, None, NSApp().mainWindow(), self, 'openPanelDidEnd:panel:returnCode:contextInfo:', None)
    except:
        pass

@AppHelper.endSheetMethod
def openPanelDidEnd_panel_returnCode_contextInfo_(self, panel, returnCode, contextInfo):

我得到的错误是:

objc.BadPrototypeError: Python signature doesn't match implied Objective-C signature for <unbound selector openPanelDidEnd:panel:returnCode:contextInfo: of controller at 0x6166a70>

2 个答案:

答案 0 :(得分:1)

beginSheetForDirectory:file:modalForWindow:modalDelegate:didEndSelector:contextInfo:已在10.6中弃用: http://developer.apple.com/library/mac/#documentation/cocoa/reference/ApplicationKit/Classes/NSOpenPanel_Class/DeprecationAppendix/AppendixADeprecatedAPI.html

在同一问题上挣扎导致PyObjC没有阻止签名http://pyobjc.sourceforge.net/documentation/pyobjc-core/blocks.html for beginSheetModalForWindow:completionHandler:你只能使用runModal

我的解决方案:

panel = NSOpenPanel.openPanel()
panel.setCanChooseDirectories_(NO)
panel.setAllowsMultipleSelection_(NO)

panel.setAllowedFileTypes_(self.filetypes)
panel.setDirectoryURL_(os.getcwd())

ret = panel.runModal()
if ret:
    print panel.URL()

panel.URL()返回用户选择。

答案 1 :(得分:1)

正如elv所说,beginSheetForDirectory:file:modalForWindow:modalDelegate:didEndSelector:contextInfo:已在10.6中被弃用,而新的使用方法是beginSheetModalForWindow:completionHandler:在Snow Leopard附带的PyObjC版本中,此方法没有元数据,但它有自添加以来,您可以自己更新相应的文件,以便您可以使用此方法。打开/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/PyObjC/AppKit/PyObjC.bridgesupport并找到元素:

<class name='NSSavePanel'>

在其中,添加以下内容:

<method selector='beginSheetModalForWindow:completionHandler:'>
    <arg index='1' block='true' >
        <retval type='v' />
        <arg type='i' type64='q' />
    </arg>
</method>
<method selector='beginWithCompletionHandler:'>
    <arg index='0' block='true' >
        <retval type='v' />
        <arg type='i' type64='q' />
    </arg>
</method>

这是Python方面为了获取并向Objective-C返回正确类型的对象所需的元数据。您可以为完成处理程序传递任何可调用对象,只要它具有正确的签名(即,接受整数参数并且不返回任何内容)。一个例子:

def showOpenPanel_(self, sender):
    openPanel = NSOpenPanel.openPanel()

    def openPanelDidClose_(result):
        if result == NSFileHandlingPanelOKButton:
            openPanel.orderOut_(self)
            image = NSImage.alloc().initWithContentsOfFile_(openPanel.filename())
            self.imgView.setImage_(image)
    openPanel.setAllowedFileTypes_(NSImage.imageFileTypes())
    openPanel.beginSheetModalForWindow_completionHandler_(self.imgView.window(), 
                                                          objc.selector(openPanelDidClose_, argumentTypes='l'))