I placed within the main GtkWindow a GtkEntry widget to show the step position (what is already done) within a running function. However it shows only the fist and the last step position. And I could not figure out how to write the concrete code.
The program structure is the following :
function main()
ui = Builder(filename =“D:\WORK\main.glade](//WORK//main.glade)”)
some code lines
signal_connect(x ->; run_job(), ui[“run”], “clicked”) # function where the GtkEntry widget is
some more code line
showall(ui[“win_main”]); end
The run_job function looks like:
function run_job()
do step 1
set_gtk_property!(ui[“verbose_info”], :text, “run_job(): step 1 done”);
set_gtk_property!(ui[“verbose_info”], :text, “run_job(): step n done”); end
Whenever the function run_job() starts I get the message within the verboase_info
GtkEntry: “run_job(): step 1 done” and when the function comes to the end “run_job(): step n done”.
No steps in between are displayed.
Therefore my question is how to manage that all steps are shown during the run of run_job().
At which place in my code I have to insert the necessary lines?
this is a really tricky one. The issue is that Julia runs on a single thread and the the UI is frozen when you are in a callback. I have recently developed a workaround for this but it requires quite some code. Since I have not so much experience with Tasks it would be great if someone else could shime in here and tell us if we have some major limitation in Julia (or its Task machinery) or if the issue is with Gtk.jl or if we just have not found the right user code to solve it.
Here is more or less my workaround. The callback is what would be called in signal_connect:
mutable struct MyState
task::Union{Task,Nothing}
someCounter::Int
end
function asyncDo()
state = MyState(nothing, 0)
state.task = Task(()->asyncDoInner(state))
schedule(state.task)
return state
end
function asyncDoInner(state::MyState)
for i=1:100
# do something
state.someCounter = i
sleep(0.01) # I think the yield suffices
yield()
end
end
# the following function is the callback that is invoked called by signal_connect
function callback()
state = asyncDo()
timer = nothing
function update(::Timer)
if Base.istaskfailed(state.task)
close(timer)
error("something is wrong")
return
end
# Here the UI should be update. Access state.someCounter to get the progress
if istaskdone(state.task)
close(timer)
end
return
end
timer = Timer(update, 0.0, interval=0.1)
return
end