Forum Archive

Need help about ui function

wolf71
  1. using load_view('myui'), how can I get the quit event ?

  2. how to show the pick music view?

import ui

def mediaPicker_didPickMediaItems_(_self,_cmd,mediaPicker,mediaItemCollection):
    print '!!!',ObjCInstance(mediaPicker),ObjCInstance(mediaItemCollection)

mediaPickerDelegate = create_objc_class('mediaPickerDelegate',methods=[mediaPicker_didPickMediaItems_],protocols=['mediaPickerDelegate'])
mpDelegate = mediaPickerDelegate.alloc().init()

def pick_music():
    mp1 = MPicker.alloc().initWithMediaTypes_(1)
    mp1.setDelegate_(mpDelegate)
    mp1.allowsPickingMultipleItems = False

v = ui.load_view('myui')
v.present('sheet')
omz

I hope this helps:

#!python2

from objc_util import *
import ui

MPicker = ObjCClass('MPMediaPickerController')

def mediaPicker_didPickMediaItems_(_self, _cmd, _mp, _collection):
    picker = ObjCInstance(_mp)
    print '!!!', picker, ObjCInstance(_collection)
    picker.dismissViewControllerAnimated_completion_(True, None)

def mediaPickerDidCancel_(_self, _cmd, _mp):
    ObjCInstance(_mp).dismissViewControllerAnimated_completion_(True, None)

MediaPickerDelegate = create_objc_class('MediaPickerDelegate', methods=[mediaPicker_didPickMediaItems_, mediaPickerDidCancel_], protocols=['MPMediaPickerDelegate'])
mpDelegate = MediaPickerDelegate.alloc().init()

# Set "pick_music" as the action of a button in "myui.pyui"
def pick_music(sender):
    mp1 = MPicker.alloc().initWithMediaTypes_(1)
    mp1.setDelegate_(mpDelegate)
    mp1.allowsPickingMultipleItems = False
    root_vc = UIApplication.sharedApplication().keyWindow().rootViewController()
    while root_vc.presentedViewController():
        root_vc = root_vc.presentedViewController()
    root_vc.presentViewController_animated_completion_(mp1, True, None)

v = ui.load_view('myui')
v.present('sheet')
wolf71

@omz Thank you very much. it's work!

when I using load_view('myui'), how can I get the quit event (X close the main form)?

Phuket2

@wolf71 , the below is a little more than you are looking for. But it's great, not my code btw. I just did a wrapper. But the below code loads a pyui/UIFile into a Custom ui class. Opposed to loading a view into a Custom Class. Anyway, if you like using pyui files, this is so nice. But more you can do also. Just search the forum for pyui.

You can do a lot in pyui files. Define a custom clsss , mapping it to code also custom attributes. It's a long conversation, but you can do a lot.

#Pythonista Forum - @Phuket2
import ui, editor

def pyui_bindings(obj):
    # Pythonista Forum, @JonB
    def WrapInstance(obj):
        class Wrapper(obj.__class__):
            def __new__(cls):
                return obj
        return Wrapper

    bindings = globals().copy()
    bindings[obj.__class__.__name__] = WrapInstance(obj)
    return bindings

# a Custom ui class as it subclasses ui.View
class MYUIClass(ui.View):
    def __init__(self, ui_file, *args, **kwargs):
        ui.load_view(ui_file, pyui_bindings(self))
        super().__init__(*args, **kwargs)

    # this is a callback from ui, is called automatically for a custom
    # class, if the method is defined
    def will_close(self):
        print('the view will close')

    def did_load(self):
        print('the pyui file has loaded...')

if __name__ == '__main__':
    _use_theme = True
    w, h = 320, 320
    f = (0, 0, w, h)

    ui_file = 'myui'
    style = 'sheet'
    animated = False
    theme = 'Oceanic'
    hide_title_bar = False

    mc = MYUIClass(ui_file, frame=f, bg_color='white')

    if not _use_theme:
        mc.present('sheet', animated=animated,
                    hide_title_bar=hide_title_bar)
    else:
        mc.name = theme
        editor.present_themed(mc, theme_name=theme,
                            style=style, animated=animated,
                            hide_title_bar=hide_title_bar)

Edit, sorry, for this to work, you need to set the Custom Class attr in the pyui file to the class name, in this case MYUIClass

Phuket2

Another post on the subject, but there are a lot more.

jmv38

@omz i've got an error : no objectiveC MPMediaPickerController blabla... Is this ios10 only?
btw, would be nice to be able to copy the error messages.

dgelessus

@jmv38 It works on iOS 9 too. For some reason, MediaPlayer.framework (where MPMediaPickerController is from) is loaded by default on iOS 10, but on iOS 9 you first need to load it manually:

NSBundle.bundleWithPath_("/System/Library/Frameworks/MediaPlayer.framework").load()
MPicker = ObjCClass("MPMediaPickerController")

By the way, it is possible to copy error messages. When you open the traceback navigator (the red window that pops up when an exception happens) there is a "Print Traceback" option at the top of the traceback list. This prints a normal Python traceback to the console, which you can copy and paste like normal.

jmv38

thank you @dgelessus .
I dont have the print option, it must be a pythonista3 feature.

lukaskollmer

@omz doesn't iOS 10 require a NSAppleMusicUsageDescription entry in the Info.plist to access the MediaPlayer framework?

omz

@lukaskollmer Only if the app is linked against the iOS 10 SDK. The current App Store versions are linked against the iOS 9 SDK, and the betas do have that Info.plist key.

wolf71

@Phuket2 Thanks.

error:

Traceback (most recent call last):
File "/private/var/mobile/Containers/Shared/AppGroup/A393CF34-1371-47E1-B49E-D9AF34A644DC/Pythonista3/Documents/Test/test1.py", line 41, in
mc = MYUIClass(ui_file, frame=f, bg_color='white')
File "/private/var/mobile/Containers/Shared/AppGroup/A393CF34-1371-47E1-B49E-D9AF34A644DC/Pythonista3/Documents/Test/test1.py", line 20, in init
super().init(args, *kwargs)
TypeError: super() takes at least 1 argument (0 given)

Phuket2

@wolf71 , are you using Pythonista 2?

Phuket2

@wolf71 , well I guess you are. If you replace the super().xxx line as the below it will work.

class MYUIClass(ui.View):
    def __init__(self, ui_file, *args, **kwargs):
        ui.load_view(ui_file, pyui_bindings(self))
        #super().__init__(*args, **kwargs)
        ui.View.__init__(self, *args, **kwargs)
wolf71

@Phuket2 said:

ui.View.init(self, args, *kwargs)

  1. Python 2.7
  2. ui.View.init(self, args, *kwargs) work.
  3. Thank you very much. :-)
Phuket2

@wolf71 , great. The call to super is a Python 3 construct. But it's nice, because it's generic. It just calls the base class without having to refer to it absolutely. In the Python 2 version, you can see calling ui.View.init() by name. It may seem like a small difference, but it really can make life a lot easier if you chop,and change your code object model. I am just thinking about small things here. But on a medium to large project I am sure it can have a profound impact. I can only speculate as I have never done a large project in Python.

My comments above are about when you are inheriting from just one base class. You have to think a little harder(aka, have more understanding) if your are inheriting from multiple base classes (multiple inheritance).