# Refreshing Gtk widget from inside a loop

**URL:** <https://discourse.julialang.org/t/refreshing-gtk-widget-from-inside-a-loop/19117>\
**Category:** General Usage\
**Created:** [December 30, 2018, 11:56am UTC](https://discourse.julialang.org/t/refreshing-gtk-widget-from-inside-a-loop/19117 "2018-12-30T11:56:08Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Carsten](https://avatars.discourse-cdn.com/v4/letter/c/f14d63/32.png) [@Carsten](https://discourse.julialang.org/u/Carsten)\
**Post date:** [December 30, 2018, 11:56am UTC](https://discourse.julialang.org/t/refreshing-gtk-widget-from-inside-a-loop/19117/1 "2018-12-30T11:56:08Z")

</div>

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”);

```
    do step 2

```

set\_gtk\_property!(ui[“verbose\_info”], :text, “run\_job(): step 2 done”);

```
   do step n

```

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?

Thank you for any advice

---

<div class="post-metadata">

**Author:** ![Carsten](https://avatars.discourse-cdn.com/v4/letter/c/f14d63/32.png) [@Carsten](https://discourse.julialang.org/u/Carsten)\
**Post date:** [December 30, 2018, 5:54pm UTC](https://discourse.julialang.org/t/refreshing-gtk-widget-from-inside-a-loop/19117/2 "2018-12-30T17:54:01Z")

</div>

ui = Builder(filename =“D:\WORK\main.glade](//WORK//main.glade)”)

should read:

ui = Builder(filename =“D:\WORK\main.glade")

---

<div class="post-metadata">

**Author:** ![tobias.knopp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tobias.knopp/32/7551_2.png) [@tobias.knopp](https://discourse.julialang.org/u/tobias.knopp)\
**Post date:** [December 30, 2018, 9:21pm UTC](https://discourse.julialang.org/t/refreshing-gtk-widget-from-inside-a-loop/19117/3 "2018-12-30T21:21:09Z")

</div>

Hi Carsten,

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.

Cheers, Tobi

---

<div class="post-metadata">

**Author:** ![tobias.knopp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tobias.knopp/32/7551_2.png) [@tobias.knopp](https://discourse.julialang.org/u/tobias.knopp)\
**Post date:** [December 30, 2018, 9:43pm UTC](https://discourse.julialang.org/t/refreshing-gtk-widget-from-inside-a-loop/19117/4 "2018-12-30T21:43:16Z")

</div>

Here is more or less my workaround. The `callback` is what would be called in `signal_connect`:

```julia
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

```

---

<div class="post-metadata">

**Author:** ![Carsten](https://avatars.discourse-cdn.com/v4/letter/c/f14d63/32.png) [@Carsten](https://discourse.julialang.org/u/Carsten)\
**Post date:** [December 31, 2018, 11:48am UTC](https://discourse.julialang.org/t/refreshing-gtk-widget-from-inside-a-loop/19117/5 "2018-12-31T11:48:13Z")

</div>

Thank you for your prompt reply!  
I’ll give it a try beginning of January. All I’m left with is:  
A Happy New Year and best wishes!

Carsten
