Потоки в GTK3 Python - PullRequest
       6

Потоки в GTK3 Python

0 голосов
/ 04 ноября 2019

Я создаю графический интерфейс GTK в Python, и мне нужно получить некоторые данные из базы данных, что занимает довольно много времени, поэтому графический интерфейс останавливается.

Поэтому я сейчас использую Threads для запуска обновления "на заднем плане ":

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

У меня есть класс GUI со всеми соответствующими методами для манипулирования GUI. Мое решение работает 80% времени, но когда не происходит сбой GTK, и выводится следующее:

[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:

В других случаях оно работает хорошо, данные загружаются и обновляется графический интерфейс.

edit: иногда я получаю эту ошибку:

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

Иногда я нажимаю кнопку обновления несколько раз, и она работает, но в какой-то момент этого не происходит.

Mymain.py выглядит так:

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()

Есть идеи, что здесь происходит?

Маркус

1 Ответ

0 голосов
/ 04 ноября 2019

Хорошо, GTK3 не является потокобезопасным. Поэтому я изменил логику программы - выполнение запросов в новом потоке и обработка манипуляций с графическим интерфейсом в потоке графического интерфейса ONLY . Это означает, что я должен передать сигнал «запросы выполнены» в цикл обработки событий:

Создание нового сигнала и его регистрация:

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)

Поэтому, когда я нажимаю кнопку, запускаюпоток:

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

В этом потоке выполните вычисления, а затем подайте сигнал:

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

, чтобы после выполнения вычислений / запросов / чего бы то ни было выполнено обратный вызови это работает!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...