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.
Console output from ui
-
I wrote a script that is controlled via an ui and outputs what it does through the console.
My problem is that it doesn't output the data in realtime.
My code works like the following example.
The time.sleep(5) is just some time consuming task.
I would like to have an output like thisa
b
waiting 5 seconds
c
dInstead the output is
a
waiting 5 seconds
b
c
d# coding: utf-8 import ui, time, tempfile ui_file = '[{"selected" : false,"frame" : "{{0, 0}, {240, 240}}","class" : "View","nodes" : [{"selected" : true,"frame" : "{{75, 49}, {80, 32}}","class" : "Button","nodes" : [],"attributes" : {"action" : "button","frame" : "{{80, 104}, {80, 32}}","title" : "Button","class" : "Button","uuid" : "269E121F-FCD6-478B-B6CD-2F2C2D3E2ED8","font_size" : 15,"name" : "button1"}}],"attributes" : {"enabled" : true,"background_color" : "RGBA(1.000000,1.000000,1.000000,1.000000)","tint_color" : "RGBA(0.000000,0.478000,1.000000,1.000000)","border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)","flex" : ""}}]' def button(sender): print 'b' time.sleep(5) print 'c' open('Test_abcd.pyui', 'w').write(ui_file) print 'a' v = ui.load_view('Test_abcd') v.present('sheet') v.wait_modal() print 'd'
-
Try replacing
time.sleep(5)
withui.delay(None, 5)
... I am not sure if it will do the right thing or not.If not, you could create a function called
print_c()
that doesprint('c')
and then doui.delay(print_c, 5)
. -
Thanks for your reply.
Maybe my example was a bit to simple.
time.sleep(5) is a placeholder for downloading files (which takes some time).
print c indicates, that the download is finished. So this should follow the sleep.
My problem is that the b isn't printed before the download starts.If I only run button() everything works fine. Running button() via the ui prints b and c at the same time (after 5 secs).
I want it to print b, work, print c. -
The typical way you handle long running callbacks is to use the ui.in_background decorator. Remember, a button action needs to exit wuickly, or the ui appears frozen.
However, that does not work with wait_modal -- not sure if that is a bug or a documentation quirk. Basically, wait_modal seems to use the same single background thread, so anything backgrounded gets run after the dialog is closed.
The solution is to use ui.delay to launch another function containing your slow process.
def button(sender): print 'b' def other(): time.sleep(5) # call to some time consuming task print 'c' ui.delay(other,0.01) #easy way to launch a new thread
Another option would be to use this run_async decorator on you action, which actually runs the function a background thread, as opposed to queuing it up..
def run_async(func): from threading import Thread from functools import wraps @wraps(func) def async_func(*args, **kwargs): func_hl = Thread(target = func, args = args, kwargs = kwargs) func_hl.start() return func_hl return async_func
-
@JonB gave better advise than I did...
import ui def download(): print('download') print('a') ui.delay(download, 0.02) print('b')
-
Thank you all for your help.
After some fumbling around I decided to close the UI and then start the action.
This was the easiest way without having to change much code :)