2009-05-10 30 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 

私は心配ですメインの2行は、次のとおりです。

 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を試してみました。これを処理する最善の方法は何ですか?

答えて

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を使用しています。私はあなたのパネルがselfの財産である必要があるとは思わないが、それはあなたのリターン機能で得られるからだ。 objcの規約は、関数の最初の文字を小文字にすることです。

+0

ありがとうございます、今週末に試してみます! –

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

ダンのコードも同様に動作しますが、私の変種はslighly明確です私見:あなたは、実際のメソッドが、そのすべきメソッドの名前を渡しません呼び出される。

+0

そんなやり方にするのが有利でしょうか?私は実際のメソッドを渡すのが好きです。なぜなら、メソッドがファーストクラスのオブジェクトであるというより、「pythonic」を感じるからです。そして、b)Xcodeはメソッドの名前を自動的に補完しますので、タイプミスを心配する必要はありません。また、c)私が望むなら、変数にエンドセレクタを保持させることができます。 – Dan

関連する問題