3

我想为我正在设计的应用程序使用 NSOpenPanel。这是我到目前为止所拥有的:

@objc.IBAction
def ShowOpenPanel_(self, sender):
    self.panel = NSOpenPanel.openPanel()
    self.panel.setCanChooseFiles_(False)
    self.panel.setCanChooseDirectories_(True)
    NSLog(u'Starting OpenPanel')
    self.panel.beginForDirectory_file_types_modelessDelegate_didEndSelector_contextInfo_(
        self.defaults.objectForKey_(u'projpath'), 
        objc.nil, 
        objc.nil, 
        self, 
        objc.selector(self.OpenPanelDidEnd_returnCode_contextInfo_, 
            signature='v:@ii'),
        objc.nil)
    NSLog(u'OpenPanel was started.')

def OpenPanelDidEnd_returnCode_contextInfo_(self, panel, returnCode, context):
    NSLog('Panel ended.')
    if (returnCode == NSOKButton):
        NSLog(u'User selected OK')
        path = self.panel.filenames()[0]
        self.defaults.setObject_forKey_(path, u'projpath')
    del self.panel

我关心的主要两行是:

        objc.selector(self.OpenPanelDidEnd_returnCode_contextInfo_, 
            signature='v:@ii'),
        objc.nil) #this is the argument that gets passed as the void pointer

第三个参数应该是一个空指针。由于我不打算使用该数据,因此我宁愿将其留空。我尝试过制作签名'v:@iv'并尝试使用objc.NULL和 python'sNone以及所有这些东西的几乎所有组合。处理这个问题的最佳方法是什么?

4

2 回答 2

1

我认为您根本不需要使用objc.selector;试试这个:

@objc.IBAction
def ShowOpenPanel_(self, sender):
    self.panel = NSOpenPanel.openPanel()
    self.panel.setCanChooseFiles_(False)
    self.panel.setCanChooseDirectories_(True)
    NSLog(u'Starting OpenPanel')
    self.panel.beginForDirectory_file_types_modelessDelegate_didEndSelector_contextInfo_(
        self.defaults.objectForKey_(u'projpath'), 
        objc.nil, 
        objc.nil, 
        self, 
        self.OpenPanelDidEnd_returnCode_contextInfo_,
        objc.nil)
    NSLog(u'OpenPanel was started.')

我还发现我需要用以下方式装饰面板结束功能PyObjCTools.AppHelper.endSheetMethod

@PyObjCTools.AppHelper.endSheetMethod
def OpenPanelDidEnd_returnCode_contextInfo_(self, panel, returnCode, context):
    NSLog('Panel ended.')
    if (returnCode == NSOKButton):
        NSLog(u'User selected OK')
        path = self.panel.filenames()[0]
        self.defaults.setObject_forKey_(path, u'projpath')
    del self.panel

以下是我将如何写你所拥有的:

@objc.IBAction
def showOpenPanel_(self, sender):
    panel = NSOpenPanel.openPanel()
    panel.setCanChooseFiles_(False)
    panel.setCanChooseDirectories_(True)
    NSLog(u'Starting openPanel')
    panel.beginForDirectory_file_types_modelessDelegate_didEndSelector_contextInfo_(
        self.defaults.objectForKey_(u'projpath'),    #forDirectory
        None,    #file
        None,    #types
        self,    #modelessDelegate
        self.openPanelDidEnd_returnCode_contextInfo_,    #didEndSelector
        None)    #contextInfo
    NSLog(u'openPanel started')

@PyObjCTools.AppHelper.endSheetMethod
def openPanelDidEnd_returnCode_contextInfo_(self, panel, returnCode, context):
    NSLog(u'Panel ended')
    if returnCode != NSOKButton:
        return
    NSLog(u'User selected OK')
    path = panel.filenames()[0]
    self.defaults.setObject_forKey_(path, u'projpath')

变化说明:我一直使用None而不是objc.nil,它还没有搞砸我;我认为您的面板不需要是 的属性,self因为您在返回函数中获得了它;objc 约定是将函数的第一个字母小写。

于 2009-05-16T16:50:17.223 回答
1

打开面板的正确方法是:

@objc.IBAction
def showOpenPanel_(self, sender):
    panel = NSOpenPanel.openPanel()
    panel.setCanChooseFiles_(False)
    panel.setCanChooseDirectories_(True)
    NSLog(u'Starting openPanel')
    panel.beginForDirectory_file_types_modelessDelegate_didEndSelector_contextInfo_(
        self.defaults.objectForKey_(u'projpath'),    #forDirectory
        None,    #file
        None,    #types
        self,    #modelessDelegate
        'openPanelDidEnd:returnCode:contextInfo:',    #didEndSelector
        None)    #contextInfo
    NSLog(u'openPanel started')

Dan 的代码也可以,但恕我直言,我的变体更清晰:您不传递实际方法,而是传递应该调用的方法的名称。

于 2009-05-24T08:16:35.017 回答