• bitbucket158

    As a way of switching between views, I'm creating a top-level root view object and then adding/removing child views to/from that. The child views are those created with the layout editor and loaded using ui.load_view().

    What I'm finding is that if I load a view and present it, everything works fine. The view fills the screen on my iPhone 4s. If, however, I create the root view object, then add the loaded view to that and present the root view, it does not fill the screen.

    I've experimented with setting the flex attribute on the root view but this didn't seem to help (I tried 'WH' for example).

    Here's some sample code which illustrates the issue.

    import ui
    v = ui.load_view('test')
    mode = 0
    if mode == 0:
      v.present()
    else:
      rootView = ui.View()
      rootView.add_subview(v)
      rootView.present()
    

    The above code is in test.py and there's a simple test.pyui to go along with it. In the above, I'm manually toggling the mode variable value to test things. If mode == 0, it works correctly and the UI fills the screen. If mode == 1 it does not fill the screen.

    Any suggestions?

    posted in Pythonista read more
  • bitbucket158

    The above worked great for a single subview. I then tried removing the first subview and adding a second (as a way to switch between views).

    The second view exhibited the original problem, it didn't fill the screen.

    I found the solution here was to set the width and height of the second subview to match that of the root view. I assume additional views will also need this.

    posted in Pythonista read more
  • bitbucket158

    I found a workaround which seems to have addressed the issue.

    Instead of creating the root view programmatically, I simply created a new 'script with ui' left it empty and named it 'RootView'. I then load this and set the child view (also loaded) flex to 'WH'.

    Here's the updated code.

    import ui
    v = ui.load_view('test')
    mode = 1
    if mode == 0:
        v.present()
    else:
        rootView = ui.load_view('RootView')
        v.flex = 'WH'
        rootView.add_subview(v)
        rootView.present()
    

    So there must be something different when loading an empty view vs creating it programmatically which causes it to fill the screen.

    This only requires creating the extra dummy root view ui script but I think provides a nice workaround.

    posted in Pythonista read more
  • bitbucket158

    @omz

    I created a label in the center of the view and set the auto resizing parameter to WH.

    It works fine if I present the loaded view directly. It doesn't work if I add it to the root view.

    Any other ideas?

    posted in Pythonista read more
  • bitbucket158

    @omz

    I modified the code using your suggestion. When I run with those mods the ui is too large. It extends beyond the bottom of the screen.

    I'm using an iPhone 4s.

    posted in Pythonista read more
  • bitbucket158

    @JonB

    I'm using Pythonista on an iPhone. The docs indicate that in that context fullscreen is the default. I did try adding the fullscreen arg though just for kicks but it didn't make a difference.

    I also tried setting the rootView size to match the subview as well as calling size_to_fit but these didn't make any difference.

    posted in Pythonista read more
  • bitbucket158

    I'm enjoying learning the new ui module and had the following question. How can I make use of multiple views? Meaning, multiple top level views which each save to a different ui file.

    For example, suppose you want to have a loading "screen" and then the main ui "screen" and want to create them separately in the ui layout tool. Is this possible in pythonista?

    Here's what I've tried without any luck.

    1. Load and present the first view, then later load and present the second view. When doing this, I get an error about a view already being presented.

    2. Same as above, but call close on the first view before calling present on the second view. This doesn't work and I get the same error.

    3. Use a single view (which isn't what I'm going for but I thought I'd try it) composed of all the sub-views in the first and second view (this is the part where it is a pain in the layout editor). Then hide all the second view sub-views and just show the first set. When ready hide the first set and show the second set. This doesn't seem to do anything. Modifying the hidden attribute doesn't seem to have any effect.

    4. Add and remove the loaded view beneath a single top level view. This doesn't seem like an option since the sub views attribute is read-only.

    Anyway, just curious if anyone else knows how to approach this. I like the ui layout tool, but for a script with multiple stages (loading, entering data, showing results) its not going to work well unless I can setup separate views and then switch between them.

    posted in Pythonista read more
  • bitbucket158

    Thank you! I was previously unable to find remove_subview in the docs, but I went back again and see it there. Thanks for the help :)

    posted in Pythonista read more
  • bitbucket158

    You can switch between sub views using the View add_subview and remove_subview methods.

    So you could start with subview 1 active then remove it and add subview 2 to replace it.

    posted in Editorial read more
  • bitbucket158

    omz, how do I "replace the subview with one you've loaded from elsewhere"? The docs indicate that the subviews attribute of the View class is a readonly tuple. So how do I go about replacing a subview with another one?

    posted in Pythonista read more
  • bitbucket158

    For showing a single view it works great. But if your app needs to switch between multiple views (maybe a loading view, then a display view, then an edit view, then maybe a settings view, etc) there doesn't seem to be an obvious way to do it.

    posted in Pythonista read more
  • bitbucket158

    I was experimenting with the location module, specifically location.geocode() to convert addresses in the contacts list to lat/lon coordinates.

    I wrote a small script which went through all the contacts and for each address in each contact, called location.geocode() and then cached the results in a file. The idea is that you just do this once and then only update the cache when the contact modification_date changes so you're not geocode()'ing them all every time.

    Anyway, I noticed it went through the list for awhile and then eventually just failed on all the remaining entries. I tried again multiple times and it kept failing. I then waited a minute or so and tried it and the remaining entries all worked.

    So... is pythonista or iOS throttling the # geocode requests you can send in some unit of time? Does anyone know what the actual limit is? There appears to be some limiting going on, I'm just curious what the actual limit is.

    posted in Pythonista read more
  • bitbucket158

    henryiii, I corrected the code - I edited it after the fact so the print provides a little more useful info besides just the index :)

    omz, thanks for the reply, must just be an iOS limit then.

    posted in Pythonista read more
  • bitbucket158

    There's not much to it. Just, as I said, looping through contacts and attempting to geocode the addresses :)

    Here's a bit of sample code which reproduces what I'm seeing. When I run this it seems to work, going through the list but it eventually gets to a point where all remaining geocode requests fail. When this happens if you immediately run it again you'll see they all fail, even the ones which worked before. If you then wait a bit and try again it'll start working.

    My conclusion was that there's some sort of throttling being applied. Maybe by Pythonista, maybe iOS, not sure. I was posting here just to see if someone knew of such a limit imposed somewhere in the stack for geocode operations and what the actual limit was.

    import location
    import contacts
    
    x = 0
    ppl = contacts.get_all_people()
    for p in ppl:
        for addrt in p.address:
            x = x + 1
            addr_tag = contacts.localized_label(addrt[0])
            addr = addrt[1]
            print(str(x) + ', ' + p.full_name + ', ' + addr_tag)
            locs = location.geocode(addr)
            if locs and len(locs) > 0:
                loc = locs[0]
                lat = loc['latitude']
                lon = loc['longitude']
                print('   ' + str(lat) + ',' + str(lon))
            else: 
                print('   ERROR: unable to locate')

    posted in Pythonista read more
  • bitbucket158

    In Pythonista I created a new script using the "Scene with Layers" template. I then attempted to define my own custom layer class using the below.

    class MyLayer (Layer):
      def draw(self):
        super(MyLayer,self).draw()
    

    My hope was to allow the base class to draw then add some custom rendering on top .

    I changed the code in the template scene setup method so it created instances of MyLayer instead of Layer to test it.

    When I run I get the following error.

    "TypeError: draw() takes exactly 1 argument (2 given)"

    Any idea what I'm doing wrong?

    posted in Pythonista read more
  • bitbucket158

    I ended up creating a function to make this even cleaner.

    def _super(self):
      return super(self.__class__,self)
    

    With this it makes it much cleaner when you want to invoke the base class.

    class MyLayer (Layer):
      def draw(self,a=1.0):
        _super(self).draw(a)
    

    A lot nicer if you're coding on an iPhone with the small display :)

    posted in Pythonista read more
  • bitbucket158

    Ah ok! Yes that is nicer. Thanks!

    posted in Pythonista read more
  • bitbucket158

    What do you mean? I'm not following your last comment.

    posted in Pythonista read more
  • bitbucket158

    I got it to work! The inspect code you posted helped. Looks like the Layer draw method takes a second optional arg, a (alpha). Adding that got rid of the error. Odd since it's optional though, but it worked!

    Here's the working code.

    class MyLayer (Layer):
      def draw(self, a=1.0):
        super(MyLayer,self).draw(a)

    posted in Pythonista read more
  • bitbucket158

    Strange ; I know I've called base class methods in other contexts but never draw and never derived from any scene classes .

    posted in Pythonista read more
Internal error.

Oops! Looks like something went wrong!