2

I'm building a GTK GUI in Python and I need to get some data from the database which takes quite long, so the GUI freezes.

So I'm now using Threads to run the refreshing "in the background":

Thread(target=self.updateOrderList).start()

I have GUI class with alle relevant methods to manipulate the GUI. My solution work 80% of the time, but when it doesn't GTK crashed and it outputs this:

[xcb] Unknown request in queue while dequeuing
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
python3.6: ../../src/xcb_io.c:165: dequeue_pending_request:

The other times it works good, the data get loaded and its refreshing the gui.

edit: Sometimes I get this error:

Gdk-Message: 11:13:42.848: main.py: Fatal IO error 11 (Die Ressource ist zur Zeit nicht verfügbar) on X server :0

Sometimes I click the refresh button several times and it works, but then it doesn't at some point.

My main.py looks like this:

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GObject

import gui

GObject.threads_init()

# start gui
gui.Gui()
Gtk.main()

Any ideas whats happening here?

Markus

Standard
  • 1,450
  • 17
  • 35
  • could be related to order in which threads run; try to ensure the GUI is fully initialised before the background thread starts putting requests into the GUI (to experiment, introduce a sleep statement on commencing the background thread) – Darren Smith Nov 04 '19 at 10:12
  • I tried but it gets triggered on a button, so waiting doesn't solve the problem. – Standard Nov 04 '19 at 10:17
  • Relevant [handling-gtk-objects-on-threads-in-python](https://stackoverflow.com/questions/33425202/handling-gtk-objects-on-threads-in-python) – stovfl Nov 04 '19 at 11:27
  • @stovfl Thanks, might be a good solution. Do you know if it also possible to do this via signals/callbacks? – Standard Nov 04 '19 at 11:52
  • It's common sense to use `GLib.idle_add(self._callback)`, see [Possible solution for Threads](https://stackoverflow.com/a/55925063/7414759) – stovfl Nov 04 '19 at 12:08

1 Answers1

4

Okay, GTK3 is not threadsafe. So I changed the program logic - doing requests in a new thread, and handling the GUI manipulation in the GUI thread ONLY. So that means I have to emit a "requests done" signal to the event loop:

Creating a new signal and registering it:

GObject.signal_new("my-custom-signal", self.window, GObject.SIGNAL_RUN_LAST, GObject.TYPE_PYOBJECT,
                       (GObject.TYPE_PYOBJECT,))
self.window.connect("my-custom-signal", self.updateOrderListCallback)

So when I click a button, start a thread:

Thread(target=self.updateOrderListThread).start()

In that thread, do the calculations, and then emit the signal:

self.window.emit("my-custom-signal", None)

so than the callback will be called after the calculations/requests/whatever are done and it works!

Standard
  • 1,450
  • 17
  • 35