Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Home Screen alias: is script already running?
-
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. -
I like to know that too. Whenever I launch my ui.View app for example via url schema and it was already running then i have two views stacked on each other. I followed two approaches to solve.
-
I start a thread and checking every second wether the app is in background. If so then I close the view. This is working but of course with the disadvantage that the view also closes when leaving pythonista for something other then restarting the script a second time.
-
On start of my script I would try two identify all current views and close them before presenting the new view. But I did not succeed to address e.g. find the views.
-
-
You may be able to check for running instances as follows
import gc, ui running_views=[v for v in gc.get_objects() if isinstance(v,ui.View) and v.on_screen]
though the on_screen check won't work for views presented as panels.
-
You could also just set some flag in a global module when your view is on-screen, and clear it when the view is dismissed. Does this make sense?
-
SOLVED
I tried a mix of both suggestions with the global variable and the instance and onscreen test. But when I launch the app the second time then the global var is empty.
Now I did the trick with the bultins class. That works fine and solves the issue nicely . Thank you so much.Here is the code
import builtinsif name == 'main':
try: v=builtins.theview except: v=None if(isinstance(v,ui.View) and v.on_screen ): #console.hud_alert('reuse view') else: #console.hud_alert('create view') v = ui.load_view() v.present('sheet') builtins.theview=v
-
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
-
Nice! Can you also see
if 'bookView' in locals() or 'bookView' in globals():
?If you do stick with try/except then I would encourage you to avoid a naked exception (see PEP8) because it can hide syntax and other errors that may take precious time to find. In this case
except NameError:
would be safer thanexcept:
. -
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 ofStuffView
, my own subclass ofui.View
, so as to be even more certain that the saved view I’m finding is the view for this app. Butisinstance
returnedFalse
; I’m assuming this is because theStuffView
class was not in locals/globals, and so I had to recreate it; but once recreated, it isn’t the sameStuffView
that the previous run of Pythonista creatednavigation
from. Whereas it is the sameui.View
that each incarnation’sStuffView
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 onbuiltins
.