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.
Exit Pythonista after shortcut invocation
-
@zinc, do you want to return to the shortcut, or just end up on the home screen?
-
End up on the home screen.
-
@zinc I use
os.abort()
-
Well, that works, but too good :-) The thing is, if I put it at the end of my script, it's not waiting for the tableview to be closed by the user, it aborts immediately.
That tells me that the .present() is not blocking, but depends on something after the script exits to continue to process the tableview. And if I do a .wait_modal() on the tableview, it locks up because it's not getting the opportunity to process.
So I tried decorating the .present with @ui.in_background and doing the .wait_modal in the foreground, but that didn't seem to work so well either.
If I could override/delegate the close action on the tableview, I could put the os.abort() there and go ahead and exit the script as normal which would continue to process the tableview until the close occurs. But it's not clear if or how I can do that.
Barring that, I tried to see if I could add a test for the active tableview object, but that requires logic that also interferes with the script exit which is clearly needed for the view to keep processing.
The other thing I looked into is to see if there's some kind of call I could make in a polling loop, to keep the tableview processing while I wait for it to finish. Something like an application.processmessages() or application.doevents() that other systems have been known to use, a call to continue the UI event processing while I check for the tableview to go away. I looked into .update() to see if that would do it, but it didn't continue to process. Also, I had trouble determining if the tableview was still present, the object continues to exist once the view is closed by the user...
I'd prefer overriding the tableview.close() but at this point, I don't know how to do either, trying to figure out what to do in the iOS/Pythonista context here...
-
@zinc normally, I always put the os.abort in the will_close method of the main presented view
-
import ui import os class my(ui.View): def will_close(self): os.abort() v = my() v.present()
-
That looks like the right approach, but I’m using a TableView, not a View- when I try that approach with a TableView:
class myTable(ui.TableView): def will_close(self): os.abort()
It throws the error, “type _ui.TableView is not an acceptable base type”
So, is there another way to override the TableView close, or will I need to create the TableView as a sub view of a parent view? I would have thought TableView inherits from View, but if that’s the case it’s not clear what I need to do different to make this work...
-
@zinc said:
will I need to create the TableView as a sub view of a parent view?
Yes
and your TableView delegate can be in the ui.View class as self
-
@zinc, the ”standard pattern” is:
import ui v = MyCustomViewWithCloseMethod() tv = ui.TableView(frame=v.bounds, flex='WH') v.add_subview(tv) v.present('fullscreen')
This way your tableview will look and behave just as if you had presented it directly.
-
Works a champ, thanks!
-
@zinc looks like you solved it, but ... I believe you can use wait_modal on the root view. Usually you will want a table view as a subviews of another view. A few View methods--including perhaps wait_modal -- might not work right.
You cannot use wait_modal from a callback, it can't run on the main thread, which is maybe the problem you had.
Also, it you are using wait_modal, you cannot have in_background on any of your button actions, since @in_background tries to queue on the same thread that is blocked when wait_modal is waiting (I think). So you have to use your own thread for one or the other.