URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 7472
[ Назад ]

Исходное сообщение
"Обновить(перерисовать) виджет (gtkmm/GTK)"

Отправлено HellFire , 10-Июл-08 11:35 
Доброго времени суток. Использую gtkmm и среду NetBeans.
Вот суть проблемы:
В многопоточном приложении есть окно с виджетом TreeView (основной поток), в TreeView динамически добавляются новые строчки (приходят сигналы из другого потока). Как вызвать перерисовку окна\виджета для динамического отображения добавленных данных? Дело в том, что они обновляются только, к примеру, при нажатии кнопок на форме, перемещении окна или хотя бы передвижении мыши, т.е. если окно не трогать - данные не обновляются.
нашел в официальной доке по gtkmm вот такой код, положил его в метод, добавляющий новую строчку:

//------------------------------------------------------------------------
            while(Gtk::Main::instance()->events_pending())
                Gtk::Main::instance()->iteration();
//------------------------------------------------------------------------

Он работает (строки таблицы обновляются без всяких действий пользователя) но! Программа с ним работает крайне нестабильно - почти сразу же вываливается с сообщениями типа:
//------------------------------------------------------------------------
(monitor_simple:6008): GLib-WARNING **: g_main_context_prepare(): main loop already active in another thread

GLib-ERROR **: file gmain.c: line 2012 (g_main_dispatch): assertion failed: (source)
aborting...
/usr/libexec/monitor_simple: No such file or directory.


terminate called after throwing an instance of 'std::out_of_range'
  what():  vector::_M_range_check


warning: Unable to set global thread event mask: generic error
Error while reading shared library symbols:
Cannot enable thread event reporting for process 6008: generic error
Cannot access memory at address 0xa4a648

/home/AID/NetBeansProjects/monitor_simple/6008: No such file or directory.
/home/AID/netbeans-6.0rc2/cnd1/bin/dorun.sh: line 82:  6008 Аварийный останов         "$pgm" "$@"
//------------------------------------------------------------------------

Вот.


Содержание

Сообщения в этом обсуждении
"Обновить(перерисовать) виджет (gtkmm/GTK)"
Отправлено arturpub , 12-Июл-08 14:33 
идея понятна ))
можно попробовать решить проблему так:
(сиплюс не знаю, так что пишу на сях ;)

gboolean callback(gpointer some_data) {
    <вставляем строку с данными из some_data>
    return FALSE; // снять этот callback, чтобы в след. итерации не выполнился
}

...
<тут мы понимаем что пора вставлять строку>
gpointer some_data = ???; // суем сюда сам TreeView и нужные данные
g_idle_add((GSourceFunc) callback, some_data);

когда в основном (гтк) треде дело дойдет до следующей итерации по событиям, ваш callback выполнится, а также перерисуется и TreeView. прям до конца не уверен, но по идее должно сработать без странных последствий. g_idle_add в gtkmm скорее всего не метод к-л класса.

http://research.operationaldynamics.com/blogs/andrew/softwar...
http://library.gnome.org/devel/gdk/unstable/gdk-Threads.html -- вот тут есть какой-то пример, найдите в документации gtkmm аналогичную секцию, может будет и там


"Обновить(перерисовать) виджет (gtkmm/GTK)"
Отправлено HellFire , 14-Июл-08 16:26 
Благодарю.
Честно говоря, у меня сделать через g_idle_add() не получилось, но, став копать в данном направлении, в итоге решил проблему через  Glib::Dispatcher и Widget::queue_draw().
:)