Задать вопрос
Sly_tom_cat
@Sly_tom_cat
.

GTK: нужно открыть диалог по получению от внешней программы данных (через stdout) как?

Суть проблемы в том что я на чтение stdout внешней программы сделал отдельный поток, но создание из этого потока окна валит GTK в корки ибо в GTK все должно обрабатываться главным потоком (который rрутится в GTK.main()).

Как я понимаю мне нужно как-то пропихнуть событие чтобы главный поток обрабатывая его нарисовал нужный диалог. Ну или из главного потока надо как-то узнать что появились данные в stdout внешней программы и их нужно вывести в диалог. Можно было бы по таймеру проверять stdout, но хотелось бы какого-то "интерактива"....

Понимаю что туплю но с GTK я "на вы"...

Если что - я на третьем питоне это все делаю и на gtk3 из gi.
  • Вопрос задан
  • 150 просмотров
Подписаться 2 Простой Комментировать
Решения вопроса 1
Sly_tom_cat
@Sly_tom_cat Автор вопроса
.
Короче сам нашел.

На самом деле главный цикл обеспечивается GLib- ом. Собственно с ним я уже работал когда использовал таймеры.
Оказалось - таймер это не единственный источник, который может инициировать колбеки из главного цикла.
Есть еще такая штука как вотчеры потока, а конкретнее lazka.github.io/pgi-docs/GLib-2.0/functions.html#G...

Т.е. задаем какой поток и на какое условие мониторить (мне нужно было на событие доступности данных для чтения - это GLib.IOCondition.IN), а также указывается коллбек функция и данные которые ей передать в параметрах.
Приоритет по умолчанию это - 0.

Нюансы:
1. В колбек передается первым параметром канал, вторым условие, которое было поймано, и только третьим данные (ес даннли они были указаны при создании вотчера).
2. Колбек функция должна возвращать True если нужно продолжать мониторить, если вернуть False/None то вотчер удаляется из источников событий для главного цикла.

Вот что у меня получилось:
...
    def stderr_reader(pipe, _):
      data = pipe.readline()
      if data != "":
        logger.debug(data[:-1])
      return True

    proc = Popen([external_prog, cfgFile],
                   bufsize=1,
                   universal_newlines=True,
                   stdin=PIPE, stderr=PIPE)

    io_add_watch(proc.stderr, 0, IOCondition.IN, stderr_reader)
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы