GUI не обновляется из другого потока при использовании PyGtk - PullRequest
6 голосов
/ 14 января 2010

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

Ответы [ 4 ]

12 голосов
/ 15 января 2010

GTK + не является потокобезопасным, поэтому вам не следует просто вызывать методы обновления GUI из других потоков. glib.idle_add (или gobject.idle_add в более старых версиях PyGTK) можно использовать для этой цели.

Вместо записи:

label.set_text("foo")

вы бы написали:

glib.idle_add(label.set_text, "foo")

, что вызывает вызов функции в очереди в GTK +.

Если вам нужно запустить несколько операторов, часто проще заключить их в функцию:

def idle():
    label1.set_text("foo")
    label2.set_text("bar")
glib.idle_add(idle)

Убедитесь, что функция, переданная в idle_add, не возвращает True; в противном случае он снова будет поставлен в очередь.

Редактировать: Как указал Даниэль, сначала вам нужно позвонить gtk.gdk.threads_init() в любую точку вашей программы.

2 голосов
/ 15 января 2010

Как указано в предыдущих ответах, GTK не является "потокобезопасным", но он "ориентирован на потоки" - см. Эту страницу в темах: https://developer.gnome.org/gdk2/stable/gdk2-Threads.html

Чтобы изменить виджеты GTK из другогоВы должны использовать блокировку GTK.Вызовите gtk.threads_init() сразу после импорта модуля gtk, и затем вы можете обновить его следующим образом:

gtk.threads_enter()
# make changes...
gtk.threads_leave()

Обратите внимание, что вышеописанное не будет работать в Windows (см. Ссылку выше).В Windows вы должны использовать gobject.idle_add(), как описано выше, но не забудьте поставить gobject.threads_init() непосредственно после импорта gobject в ваш код!Функция idle_add () выполнит само обновление в основном потоке (потоке, выполняющем gtk.main ()).

0 голосов
/ 13 июня 2010

То, что сказал Йоханнес, верно, однако, поскольку GTK является оберткой для вещей glib и gobject, вы на самом деле захотите использовать gtk.idle_add (). Нет необходимости в ненужном импорте.

0 голосов
/ 15 января 2010

то же самое может быть достигнуто с помощью метода gobject.idle_add, синтаксис которого такой же, как и выше, вы должны импортировать модуль gobject

...