Forum Archive

Selectors in Python

filippocld

I am writing a script and i want this button to make an action when this button is pressed:

b1=ObjCClass('UIBarButtonItem').alloc().initWithTitle_style_target_action_('H',1,None,'bt1')

I made a function named bt1 with a simple print "HelloWorld " line inside but it doesnt print anything. I tried with objcblocks too but same result. How can i achieve this? (Basically how to run a function with a BarButtonItem)

omz

Have you tried setting the target to something other than None?

filippocld

The code is this
```import ui
from objutil import * # is a custom objc module with more funtions

def bt1():
print 'HelloWorld'

bar=ObjCClass('UIKeyboardAssistantBar').alloc()
action = ObjCBlock(bt1,argtypes=[c_void_p])
txtv=ObjCInstance(ui.TextView(background_color=(.0, .85, .0)))
b1=ObjCClass('UIBarButtonItem').alloc().initWithTitle_style_target_action_('H',1,None,'action')
b2=ObjCClass('UIBarButtonItem').alloc().initWithTitle_style_target_action_('2',1,None,None)

items=[]
items.append(b1)

group=ObjCClass('UIBarButtonItemGroup').alloc().initWithBarButtonItems_representativeItem_(items,b2)

txtv.inputAssistantItem().trailingBarButtonGroups = [group]

presentUiElement(txtv) # this presents the textview in a panel ui
```
I dont know what to set as target. I saw some websites and all of them put self but it doesnt work with python. Is there a way to use self?

JonB

action must be a selector name, which is found in target or if target is None, it will search up the reponder chain.
Why don't you create a ui.Button in Python, point its action to bt, then figure out the selector name (maybe it is sel('action')) and use that, pointing to your button's objc_ptr?

omz

Here's an example for defining an ObjC class to use as the target for your action:

from objc_util import *
import ui

UIBarButtonItem = ObjCClass('UIBarButtonItem')
UIBarButtonItemGroup = ObjCClass('UIBarButtonItemGroup')

def btnAction(_self, _cmd):
    print 'hello world'

ActionTarget = create_objc_class('ActionTarget', methods=[btnAction])
target = ActionTarget.new().autorelease()

@on_main_thread
def main():
    tv = ui.TextView(frame=(0, 0, 320, 320))
    b1 = UIBarButtonItem.alloc().initWithTitle_style_target_action_('H', 0, target, 'btnAction').autorelease()
    group = UIBarButtonItemGroup.alloc().initWithBarButtonItems_representativeItem_([b1], None).autorelease()
    ObjCInstance(tv).inputAssistantItem().trailingBarButtonGroups = [group]
    tv.present('sheet')

if __name__ == '__main__':
    main()
filippocld

Thanks, solved the problem :-)

polymerchm

On my system, (iPd Air 2, beta ...33, ios 8.4.1) 'UIBarButtonItemGroup' raises a ValueError

omz

@polymerchm The class was added in iOS 9.

polymerchm

Okay. I'll wait. One beta at a time. Beta squared is scary. Is there a simple way to list which classes are in 8.4.1?

ccc

Not long now... iOS 9 General Availability is scheduled for Wednesday.

filippocld

@polymerchm i don't know about classes but you can see available frameworks doing

import os
frameworks=os.listdir('/System/Library/Frameworks')
for f in frameworks:
    print f    

And then you can load a framework with:

from objc_util import *
ObjCClass('NSBundle').bundleWithPath_('/System/Library/Frameworks/FRAMEWORK_TO_LOAD.framework').load()