• jerry

    Thanks! I’d already checked in locals() and globals() looking for some place where the running view was still accessible; I couldn’t find it. I double-checked again and it still isn’t there.

    Capturing only the necessary exception makes sense, but for me I needed to capture AttributeError.

    Another thing I tried to do was check that builtins.navigation was an instance of StuffView, my own subclass of ui.View, so as to be even more certain that the saved view I’m finding is the view for this app. But isinstance returned False; I’m assuming this is because the StuffView class was not in locals/globals, and so I had to recreate it; but once recreated, it isn’t the same StuffView that the previous run of Pythonista created navigation from. Whereas it is the same ui.View that each incarnation’s StuffView inherits from.

    Here’s my current code to restore my views from a previous run if they exist:

    try:
        navigation = builtins.navigation
    except AttributeError:
        navigation = None
    
    if navigation and isinstance(navigation, ui.View) and navigation.on_screen:
        reviewView = navigation.subviews[0]
        inventoryView = navigation.subviews[1]
    else:
        reviewView = ui.load_view('views/reviews')
        inventoryView = ui.load_view('views/inventory')
        reviewView.flex = 'WH'
        inventoryView.flex = 'WH'
    
        if isPhone:
            inventoryView.remove_subview(inventoryView['kinds'])
            titleView = inventoryView['titles']
            titleView.width = inventoryView.width-12
    
        navigation = StuffView(frame=inventoryView.frame, name='Books & Stuff')
        navigation.add_subview(reviewView)
        navigation.add_subview(inventoryView)
        navigation.present()
        builtins.navigation = navigation
    

    One of the things I’m assuming here is that .add_subview will always add subviews in the same order. I couldn’t find any means of getting a subview back by name that wouldn’t have been more work than just saving the subviews on builtins.

    posted in Pythonista read more
  • jerry

    Thank you! It worked for me, too:

    import builtins
    
    try:
        bookView = builtins.navigation
    except:
        bookView = None
    
    if bookView and isinstance(bookView, ui.View) and bookView.on_screen:
        print('Reusing existing book view')
        navigation = bookView
        inventoryView = builtins.inventory
        reviewView = builtins.reviews
    else:
        reviewView = ui.load_view('views/reviews')
        inventoryView = ui.load_view('views/inventory')
        reviewView.flex = 'WH'
        inventoryView.flex = 'WH'
    
        if isPhone:
            inventoryView.remove_subview(inventoryView['kinds'])
            titleView = inventoryView['titles']
            titleView.width = inventoryView.width-12
    
        navigation = StuffView(frame=inventoryView.frame, name='Books & Stuff')
        navigation.add_subview(reviewView)
        navigation.add_subview(inventoryView)
        navigation.present()
        builtins.navigation = navigation
        builtins.inventory = inventoryView
        builtins.reviews = reviewView
    
    

    posted in Pythonista read more
  • jerry

    I used “Add to Home Screen” to put a link to my app on my iPad. If I use the link, it starts up the app fine; if I switch to something else, and then hit the link again, it starts up a second (or third, etc.) instance of my app on top of the previous instance.

    If I use the X in the upper left corner to close the latest instance, the older instance is underneath, still working.

    How can I tell whether or not my app is already running, and not open a new instance but rather just let the existing instance display?

    I’ve looked at the list from globals() and don’t see anything obvious there.

    posted in Pythonista read more
  • jerry

    Thanks. Both of these work great.

    posted in Pythonista read more
  • jerry

    In Pythonista my app resides in its own folder ("Book Notes"). While doing the initial testing, of course, the initial working directory when running the app was always the same, since I was always starting up from the same .py file.

    Now that I’ve saved my app to the home screen, it seems to sometimes start up with the initial working directory set to the folder the app’s main file is in; and sometimes with the initial working directory set to Pythonista’s Documents folder (Pythonista3/Documents).

    So what I do currently is check to see if the current working directory ends in "/Book Notes", and if it does not, using os.chdir to change into "/Book Notes".

    Is there something else I should be doing to ensure a consistent initial working directory?

    posted in Pythonista read more
  • jerry

    I have the following text in a document I often view in Editorial:

    L’esprit has other meanings as well, but, of course, so does *mind*—and, for that matter, in English at least, so does *brain*.
    

    Editorial emphases everything from the beginning of “mind” to the end of “brain”. I’m guessing that it is the lack of what Editorial sees as an approved word-break character, causing it to ignore the asterisk after “mind”. A space, comma, or period, for example, will cause the second asterisk to end italicization. But a bracket, brace, or parenthesis does not. (Nor am I sure that they should, since I don’t know what they would mean without a space in front of them.)

    I notice that the markdown interpreter in the preview as I type this post recognizes an asterisk followed by a Chicago em dash as a valid place to end italicization:

    L’esprit has other meanings as well, but, of course, so does mind—and, for that matter, in English at least, so does brain.

    posted in Editorial read more
  • jerry

    Thank you! That was the issue. For future reference, here is the code that works:

    from scene import *
    import photos
    
    class MyScene(Scene):
        def __init__(self, mapimage):
            self.mapimage = mapimage.convert('RGBA')
            super(MyScene, self).__init__()
    
        def setup(self):
            self.mapimage = load_pil_image(self.mapimage)
    
        def draw(self):
            background(1, 1, .5)
            image(self.mapimage, 0, 0)
        
            # Draw a red circle for every finger that touches the screen:
            fill(1, 0, 0)
            for touch in self.touches.values():
                ellipse(touch.location.x - 50, touch.location.y - 50, 100, 100)
        
    mapimage = photos.pick_image(show_albums=True)
    if mapimage:
        scene = MyScene(mapimage)
        run(scene, frame_interval=1)
    else:
        print 'Canceled or invalid image.'

    posted in Pythonista read more
  • jerry

    Yes, mapimage.show() displays it in the console. I made this change to test it:

    if mapimage:
        scene = MyScene(mapimage)
        run(scene, frame_interval=1)
        mapimage2 = mapimage.convert('RGBA')
        mapimage.show()
        mapimage2.show()
    else:
        print 'Canceled or invalid image.'
    

    I tried this on all of the images I'd been using for testing, and in each case, I saw the image twice in the console after hitting the "x" in the upper right of the scene. But it still displays just a white rectangle (surrounded by yellow) in the scene (which I can move red dots around on).

    posted in Pythonista read more
  • jerry

    Are you sure you didn’t make any other changes to get it to work? I verified before adding the super() call that I was able to drag red dots across the screen; and after adding super() I still see only a white rectangle in the lower-left where the image ought to be. (Dragging red dots continues to work.)

    posted in Pythonista read more
  • jerry

    I’m playing around with displaying a photo from the photo library in a very simple script; however, I’m doing something wrong: where the image should be, it displays white in the shape that the image ought to be:

    from scene import *
    import photos
    
    class MyScene(Scene):   
        def __init__(self, mapimage):
            mapimage2 = mapimage.convert('RGBA')
            self.mapimage = load_pil_image(mapimage2)
    
        def draw(self):
            # This will be called for every frame
            background(1, 1, .5)
            fill(1, 0, 0)
            
            image(self.mapimage, 0, 0)
    
            # Draw a red circle for every finger that touches the screen:
            for touch in self.touches.values():
                ellipse(touch.location.x - 50, touch.location.y - 50, 100, 100)
        
    mapimage = photos.pick_image(show_albums=True)
    if mapimage:
        scene = MyScene(mapimage)
        run(scene, frame_interval=1)
    else:
        print 'Canceled or invalid image.'
    

    Touching the screen drags one or more red circles around, but the image doesn’t appear.

    posted in Pythonista read more

Internal error.

Oops! Looks like something went wrong!