如何在PyObjC选择器中表示空指针?
我想在我设计的应用程序中使用一个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 的 None
,以及这些东西的各种组合。请问处理这个问题的最佳方法是什么?
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的约定中,函数的第一个字母通常是小写的。
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的代码也能正常工作,但在我看来,我的写法稍微清晰一点:你传递的不是实际的方法,而是应该被调用的方法的名字。