Im investigating Gtk.jl for GUI apps - specifically, multithreading with progress updates in the GUI.
I wish to have a single window that can be used to select params, then also display progress.
I can update a progressbar in the GUI, taking items from a Channel that is fed from spawned tasks - but only if If i have no signal_connect in my script.
The signal_connect is for buttons used to select params for the work.
If i have any widgets in the app that use signal_connect (ie buttons), the GUI is frozen until all background work is completed - so i cant update a progressbar while work is being done. It seems to me that the signal_connect keeps the main thread busy by listening for events. Using Observables or GtkObservables didnt help, all the updates were only applied after the work was done.
I found i can use a GUI with buttons, to select params, then auto open another GUI to show progress/results. But thats a bit mad.
I looked around the Gtk docs for some way to disable the signal_connect when the “start” button is clicked - so as to free up the main thread for feedback updates, but couldnt find any that worked through Gtk.jl.
I know that C++ Gtk apps can do what i want, so i think the issue is not Gtk itself.
I tried popping the gtkgrid layout and reshowing it without the buttons, but it didnt work.
Anyone know a way to disable the buttons, or the signal_connect, so as to free up the main thread for GUI updating? Or some other way?
The callback should do no work but directly return. The work should be put into an idle_add block.
See also this thread: Threading 1.3: Success Story - #2 by tobias.knopp
That is actually a better example. You would start Julia with
-t 2 and the
@spawn command will offload the work to a worker. The
idle_add than communicates from the worker to the UI threads and passes it update commands.
Hi Tobias, thanks for your replies.
This edited reply is to correct my first reply where i tested that code in VScode and setting the env var there didnt start multiple threads, so i didnt get the updating expected until using CLI with -t.
with multiple threads it updates the progress as desired. but with one thread the UI is frozen until the work is done.
ok, that is expected. The code will not work with only one thread. Just define JULIA_NUM_THREADS=2 globally in your bashrc.
I have played around with this for a couple of days.
The suggestion from @tknopp was the solution. Thanks!
i found that the spawned thread with the g_idle_add UI updates needs to totally take over the UI updating, and no UI updates should be from the main thread, or the UI will be blocked to any updates. Finding out this unexpected detail was a frustrating process.
On a spawned thread to handle all the background work required, containing this code whenever a UI update is required:
Gtk.GLib.g_idle_add(nothing) do user_data
set_gtk_property!(gtkprogressbar, :fraction, progress_fraction)
Cint(false) # must have and must be false
This example shows a progressbar, but any widget can be updated, such as text.
created a blog with a template for a GUI with multithreading and progress.
check it out if interested, and maybe can suggest corrections or improvements.