Вопрос

У меня проблема с потоками в pygtk.Мое приложение представляет собой программу, которая загружает изображения из Интернета, а затем отображает их с помощью pygtk.Проблема в том, что для того, чтобы сделать это и сохранить отзывчивость графического интерфейса, мне нужно использовать потоки.

Итак, я выполнил обратный вызов после того, как пользователь нажал кнопку «Загрузить изображения», и я вызываю метод для загрузки изображений, находящихся в том же классе.

thread.start_new_thread(self.images_download, (путь, страницы)

Это не сработает.Единственный способ заставить мою программу попасть в поток - это использовать

gtk.threads_init()

Прежде чем начинать любую тему.Теперь он загружает изображения, но графический интерфейс не отвечает.Я погуглил это и попытался поместить gtk.threads_enter и gtk.threads_leave вокруг потоков, но это просто не работает.

Это было полезно?

Решение

Ваш вопрос немного расплывчатый, и без ссылки на ваш реальный код трудно предположить, что вы делаете не так.

Итак, я дам вам несколько советов, которые стоит прочитать, а затем выскажу предположения, основанные на опыте.

Прежде всего, вы, кажется, думаете, что обеспечить отзывчивость графического интерфейса можно только с помощью потоков.Это неправда.Вы также можете писать свой код асинхронно и делать все в однопоточном приложении. витой построен на этой модели программирования.Я недавно сделал запись в блоге это объясняет, как я создал интерфейс асинхронных задач, а также примеры запуска как для CLI, так и для GTK+.Вы можете посмотреть эти примеры, чтобы увидеть, как задачи могут быть реализованы асинхронно, при этом пользовательский интерфейс по-прежнему будет обновляться.

Во-вторых, если вы по какой-то причине предпочитаете использовать потоки, вам нужно будет немного разобраться в модели потоков GTK+.

Вам стоит начать с прочтения Запись часто задаваемых вопросов по PyGTK по этому вопросу., и вы можете найти этот пост в блоге тоже легко понять.

Теперь перейдем к предположениям.Я предполагаю, что вы пытаетесь обновить свой GTK UI из потока и неправильно обрабатываете блокировку.В этом случае вам лучше сейчас отложить все обновления пользовательского интерфейса, которые вы хотите выполнить, из потоков в основной поток, используя gobject.idle_add(). Таким образом, все вызовы пользовательского интерфейса будут выполняться из основного потока.Этой ментальной модели легче следовать при программировании.

Как только вы почувствуете, что действительно понимаете модели потоков и блокировки, вы можете рассмотреть возможность обновления пользовательского интерфейса из своих потоков, но легко пропустить threads_enter()/threads_leave().

Другие советы

Вы можете использовать gtk.gdk.threads_init(), чтобы позволить любому потоку изменять пользовательский интерфейс с помощью соответствующей блокировки gtk.gdk.threads_enter() и gtk.gdk.theads_leave(), но проблема в том, что это не хорошо работать на окнах.Я тестировал его в Linux, и он работает довольно хорошо, но мне не удалось заставить его работать над Win32.

=== Редактировать ===

Я просматривал это, вы можете использовать gobject.io_add_watch, чтобы проверить, есть ли что-то в вашем сокете, захватить это и затем обновить графический интерфейс.проверьте мой пост об этом:Сокеты (и некоторые другие файлы) и PyGTK без потоков.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top