• If your concern is about reading confidential files (versus writing files, etc) then one option is to keep sensitive files encrypted in the app (not appgroup) folder, and have wrench items that move files in/out of that "vault". Basically you have a "lockdown" wrench item, and an "unlock" wrench item. This would be slow but probably you would only lockdown critical files.

    You would likely chmod that folder to remove execute access, preventing anyone from reading the directory.

  • @AlexHevc, oh, the title, yes, sorry...

    Windows has an iCloud syncing client. Does it see the Pythonista iCloud folder? If yes, you could just edit files in that folder on Windows, and then run on an iOS device.

  • @Slimebot32, you are missing self both in the method definition and in the way you are calling it. Look at the other methods for reference.

  • Convenient view alignment

    Enabled views have an align attribute that supports aligning matching attributes of views. For example, aligning the heights of two views:


    Alignment example

    Using align is especially convenient when you need to align several views at once:

    view_a.align.center_x(view_b, view_c)

    In addition to all the regular constraint attributes like height and center_x in the examples above, align supports aligning the composite attributes size and center.

    Convenient view placement within superview

    Creating individual constraints can quickly become a bit of a bore. Thus the wrapper includes a number of methods for "docking" views.

    For example, the following places constraints to the top and both sides, leaving height still undefined:


    Dock top example

    Following docking methods are available:

    all, center, horizontal, vertical, horizontal_between, vertical_between, top, bottom, leading, trailing, top_leading, top_trailing, bottom_leading, bottom_trailing

    The most specialized of these are the _between methods, which dock the view to the sides in one direction, and between the two given views in another. Here's an example:

    result_area.dock.horizontal_between( search_button, done_button)

    Dock between example

    By default, dock methods leave a margin between the edges of the superview and the view. This can be adjusted with the fit parameter:

    Dock.MARGIN (the default) - standard margin Dock.TIGHT - no margin Dock.SAFE - align to the safe area insets, if applicable

    You can also change the default by setting the Dock.default_fit parameter, e.g.:

    Dock.default_fit = Dock TIGHT

    Many dock methods support share and constant parameters.

    share parameter can be used to define how much of the superview's area the view should take:


    This is only exact if you use TIGHT fit, as there is no way to dynamically account for the space taken by margins.

    constant parameter can be used to adjust the margins manually, although I feel that this is probably bad layout design.

  • Thanks, I'll try the key/value observer method.
    Gotta say it's awfully weird that Apple provided no reasonable API for this...at least for observing the value, if not setting it.

  • My God, I've just found this , thus I wasn't the first 😂

  • hmm, it turns out when the view is not on the screen, even for panel, it is removed from the view heirarchy... this is different from what i remember.

  • @cvp


    I didn't have a test because I didn't have time to try it.
    I'll take a test on the weekend.

  • Just to elaborate a little, I have tried:

    html link <a href="#link"></a> and target <a name="link"></a> markdown link with <a name="link"></a> target multimarkdown 6 convention Link [link] and [Target]{target]

    Some of these appear as links in Preview, but none navigates.

  • @bennr01 just want to confirm that installing PyDrive via pip on raspbian downloads pyasn1 0.4.5

    This is not the same with pip in stash 7.1.

    But I honestly don’t know how much it matters.

  • You will need to adapt your script a little for the pythonista environment. winsound is obviously a module for doing sound on Windows. Pythonista has a sound module that can play sounds, so you will maybe need to write a little mysound wrapper that provides a common interface if you want the same code to work both places

  • @JonB thanks again for coming to the rescue (I remember you helped me with turtle2).

    Let me indicate what I did:

    1.installed PyDrive with Stash running in 2.7 which installed to Site packages 2. I realized this when I tried to run the following code in python 3.6

    from pydrive.auth import GoogleAuth from pydrive.drive import GoogleDrive import webbrowser # Create local webserver and auto handles authentication. # Standard webbrowser gave an error, JonB found the solution if not hasattr(webbrowser,'_open'): webbrowser._open=webbrowser.open def wbopen(url, *args,**kwargs): return webbrowser._open(url) webbrowser.open=wbopen gauth = GoogleAuth() gauth.LocalWebserverAuth() # upload drive = GoogleDrive(gauth) file1 = drive.CreateFile({'title': 'Hello.txt'}) # Create GoogleDriveFile instance with title 'Hello.txt'. file1.SetContentString('Hello World!') # Set content of the file from given string. file1.Upload() file1 = drive.CreateFile({'title': 'pyconnect.py'}) # Create GoogleDriveFile instance with title ... file1.SetContentFile('pyconnect.py') # Set content of the file from given file file1.Upload()

    and received an import error.

    Installed PyDrive again in stash running python 3.6. Now I have the PyDrive module in both site packages.

    Tried to run code and received an error in line 202 of the discovery.py dependency.
    I need to admit that I have not done a pip install of pyasn1 because the printout on the PyDrive install stated that the dependency was already there.

    I appreciate your help.
    Since I have PyDrive installed in both site packages. My questions are:

    1.Do I still need to reinstall pyasn1 like you did originally?

    @cvp is running PyDrive in python3. Can PyDrive by installed using stash running 3.6? I plan to use PyDrive in python3 exclusively. I use this for education. (Full disclosure: I am a lousy teacher and an even worse student).

    Why would I get a syntax error in discovery.py (which I am not even sure what it is.) Can I reinstall this modul again without errors from pip install?

    @shinyformica thanks for the offer for help. I will probably take you on it was I reach the authentication stage. I have already complete my google console step, downloaded the unknown file, remained and move to my current directory.

    Thank you everyone for taking time from your surely busy schedules to help me.
    Thank yo in advance for any further guidance.
    I want to install PyDrive on pythonista on my students so they can automate checking their work.


  • @Tower 👍

  • In terms of how to package code -- gist is obviously the easiest, since it comes built into the app. Git is available in stash or the working copy app, and is another good way. A rarely used method is to create an executable url, which opens a script directly into the app. Some have made their modules available on pypi. You could also just zip the files up and place somewhere, with a one liner to install (see the stash GitHub repo for such an example)

  • @cvp yeah...same here, no success with any of the things that seem like they should let me modify the back or left button items to something I am in control of.

    The good news is that @mikael 's pointer to the hidden notification works perfectly, so I'm good to go.

  • I finally found the issue. The code works fine on the main level of the app, but has these issue when triggered from a event handler (a function call from an action attribute). The following directive solves the issue:

    import location @ui.in_background def button_tapped(sender): location.start_updates() loc_dic = location.get_location() addr_dic = location.reverse_geocode(loc_dic) ...
  • @JonB true enough...double conversion isn't necessary, was just writing fast...here's a simplified version:

    def popoverPoint(topView, sourceView, pos): import objc_util x,y = pos srcobjc = sourceView.objc_instance topobjc = topView.objc_instance p = srcobjc.convertPoint_toView_(objc_util.CGPoint(x,y), topobjc.superview()) return (p.x,p.y)

    This is a popup to display a list of options to the user, so the popover has a TableView subview, and tapping an item in that view dismisses the popover. Working nicely now that it shows up where expected.

Internal error.

Oops! Looks like something went wrong!