Skip to content
Advertisement

Gtk.Spinner in Python GTK while importing large library

I have a GTK application in C that will spawn a Python GTK process to embed a matplotlib figure into a window in the C process using GtkSocket/GtkPlug (uses XEmbed Protocol). The problem I am having is that the import of the matplotlib library takes about 2.5 seconds and during that time the socket widget is simply transparent. I would like to place a Gtk.Spinner in the plug (so the Python side) before the matplotlib import and have the spinner animate asynchronously during the process of importing the matplotlib library. The problem is that in order for the widget to be placed in the plug, and subsequently, for the Gtk.Spinner to animate, it requires iterations of the GTK main loop. I have approached this from a ton of different angles:

(1) Using a thread. The first attempt was trying to run Gtk.main_iteration() via the thread, however, GTK can only be run on the main thread and this does not work. It stalls the program.

(2) Then I tried to use GObject.idle_add from the thread, where the main loop iterations would run from the idle function (apparently the function called via idle is done on the main thread?), but this didn’t work either.

(3) Then I tried to import the modules on the thread, while the main thread runs the Gtk.main_iteration()’s to allow the spinner to spin while the imports are taking place. The idea was once the imports are complete, a boolean flag would change to trigger a break from the loop of main iterations. In this case the spinner appears and spins but the plot never shows up. I get an X Server error:

JavaScript

(4) In lieu of threading, I tried to use GObject.timeout_add to call a function regularly that would perform the Gtk.main_iteration()’s, but doing that results in the original behavior where the socket/plug is transparent until the plot shows up (i.e. no spinner appears nor spins).

I have run out of ideas and now I am coming here hoping for an assist. They key idea is to get the Gtk.Spinner spinning while the Python script is loading the matplotlib library, and once that is done, replace the spinner widget with the figure (while all of this is taking place in a GtkSocket/Plug). I have not created a minimal reproducible example for this since it would be rather complex given the circumstances, but if anyone that is willing to help requests one I could come up with it. However, the relevant code section is below (with previous attempts commented out):

JavaScript

Any pointers or ideas would be greatly appreciated.

Advertisement

Answer

The solution was performing the imports on a thread while allowing the main thread to do the main loop iterations. Simply doing “import ” did not work. Some previous Stack Overflow posts that were useful are here:

Python thread for pre-importing modules

import a module from a thread does not work

Import python modules in the background in REPL

The solution looks like this:

JavaScript
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement