окно gtkmm остается пустым - PullRequest
0 голосов
/ 12 января 2012

В нашем проекте мы используем gtkmm, и у нас есть несколько классов, которые расширяют Gtk::Window для отображения нашего графического интерфейса.

Теперь я выяснил, какой вызов вызывает поведение (описано впредыдущая версия. Вопрос теперь немного изменился.)

Мы показываем одно окно, работает как шарм.

Затем у нас есть окно, в котором отображаются различные сообщения о состоянии.Давайте назовем это MessageWindow.У него есть метод setMessage(Glib::ustring msg), который просто вызывает метку set_text().

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

Для всех окон: Главный поток вызывает show() для окна и создает новый поток, который вызывает Gtk::Main::run() (без аргумента).

Так и должно быть до сих пор.

Проблема начинается здесь: Основной поток теперь хочет вызвать MessageWindow::setMessage("any string").а) если я вызываю этот метод, окно сообщений реагирует совершенно корректно. Но после этого окно панели инструментов отображается пустым.б) если я его не вызываю, окно сообщения не меняет метку (что абсолютно ясно), и окно панели инструментов отображается так, как должно.

Похоже, что окна портятся каждыйпрочее.

Теперь вопрос:

Если мой gui-thread блокируется в Gtk::Main::run(), как теперь я могу изменить текст метки?

Мы используем gtkmm-2.4 (и нет, мы не можем обновить)

Любая помощь приветствуется.

1 Ответ

1 голос
/ 12 января 2012

Вау! Это сложно ...

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

Теоретически возможно заставить его работать (в Linux; в Windows это невозможно), но это больше проблем, чем стоит.

Второе: строка Gtk::Main main(argc, argv) - это не вызов, это объявление объекта. Объект main должен жить в течение всей программы, поэтому, если вы используете его в конструкторе объектов, как только вы вернетесь из него, объект будет уничтожен! Просто поместите его в верхнюю часть основной функции и забудьте об этом.

ОБНОВЛЕНИЕ : Мой обычный подход заключается в создании канала, g_io_channel для чтения и записи байтов на другом конце.

Другой вариант, хотя я не проверял, это вызвать get GMainContext основного потока, а затем g_idle_source_new() и присоединить этот источник к основному контексту с помощью g_source_attach(). Если вы попробуете это, и это сработает, пожалуйста, опубликуйте свой результат здесь!

...