2009-05-10 6 views
3

내가 디자인하고있는 응용 프로그램에 NSOpenPanel을 사용하고 싶습니다. 여기에 지금까지이 작업은 다음과 같습니다PyObjC 선택기에서 void 포인터를 어떻게 표현합니까?

@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과 파이썬의 None을 사용해 보았다. 이것을 처리하는 가장 좋은 방법은 무엇입니까?

답변

1

나는 objc.selector을 전혀 사용할 필요가 없다고 생각합니다. 대신이 시도 :

여기
@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): 
    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으로 끝 패널 기능을 장식 할 필요가 있음을 발견했습니다

@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') 

변경 사항 : objc.nil이 아닌 항상 None을 사용하며 아직 나를 망치지 않았습니다. 귀하의 패널이 self의 재산 일 필요가 있다고 생각하지 않습니다. objc 규칙은 소문자로 함수의 첫 번째 문자를 갖는 것입니다.

@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') 

댄의 코드뿐만 아니라 작동하지만 이럴 내 이체가 두드러 명확 :

+0

감사합니다. 이번 주말에 사용해 보겠습니다. –

1

패널을 열 수있는 올바른 방법은 당신이 실제 방법 그러나 메소드의 이름을 통과하지 않도록해야 불리다.

+0

그런 식으로하는 것이 이점이 있습니까? a) 메소드가 first-class 객체 인 방법으로 "pythonic"이 느껴지고 b) Xcode가 자동으로 메소드 이름을 완성하므로 typos에 대해 걱정할 필요가 없습니다. 또한 c) 원하는 경우 변수에 최종 선택기를 유지시킬 수 있습니다. – Dan