Проблема с openPanelDidEnd в PyObjC в 10.6
Следующий код, который работал нормально под 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 ответа
Как отмечает эльф, beginSheetForDirectory:file:modalForWindow:modalDelegate:didEndSelector:contextInfo:
устарел в 10.6, и новый метод для использования beginSheetModalForWindow:completionHandler:
В версии PyObjC, поставляемой со Snow Leopard, нет метаданных для этого метода, но с тех пор он был добавлен, и вы можете обновить соответствующий файл самостоятельно, чтобы использовать этот метод. Откройте /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'))
beginSheetForDirectory: файл:modalForWindow:modalDelegate:didEndSelector:contextInfo: устарел в 10.6: http://developer.apple.com/library/mac/#documentation/cocoa/reference/ApplicationKit/Classes/NSOpenPanel_Class/DeprecatedAixDad
борется с той же проблемой, потому что PyObjC не имеет подписи блока http://pyobjc.sourceforge.net/documentation/pyobjc-core/blocks.html для beginSheetModalForWindow: завершению Handler: и вы можете использовать только 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 () возвращает выбор пользователя.