Как мне представить пустой указатель в селекторе PyObjC? - PullRequest
3 голосов
/ 10 мая 2009

Я хочу использовать 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

Третий аргумент должен быть указателем void. Поскольку я не собираюсь использовать эти данные, я бы просто оставил их пустыми. Я попытался сделать подпись 'v:@iv' и попытался использовать objc.NULL и Python None, и почти все комбинации всех этих вещей. Каков наилучший способ справиться с этим?

Ответы [ 2 ]

1 голос
/ 24 мая 2009

Правильный способ открыть панель:

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

Код Дэна тоже работает, но, ИМХО, мой вариант немного яснее: вы передаете не метод, а имя метода, который должен быть вызван.

1 голос
/ 16 мая 2009

Я думаю, вам вообще не нужно использовать 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 должно иметь первую букву вашей функции в нижнем регистре.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...