【问题标题】:Problem With openPanelDidEnd in PyObjC in 10.610.6 中 PyObjC 中 openPanelDidEnd 的问题
【发布时间】:2010-09-28 02:48:12
【问题描述】:

以下在 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>

【问题讨论】:

    标签: python objective-c macos pyobjc


    【解决方案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 对于 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() 返回用户选择。

    【讨论】:

      【解决方案2】:

      正如 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'))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-14
        • 1970-01-01
        • 1970-01-01
        • 2016-08-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多