2013-07-03 4 views
1

У меня есть программа (написанная на C, в настоящее время работающая на Mac OS X 10.8.4), которая имитирует мир и обновляет состояние мира несколько раз в секунду.GTK + 3 многопоточность

При запуске эта программа создает фоновый поток, который создает простое окно GTK и вызывает gtk_main.

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

Есть ли какой-то механизм, в котором основной поток может обновить какое-то состояние в графическом потоке, а затем очередь на событие, которое запрашивает рисование графического потока? То есть

void draw() { 
    // This can only be called from the graphics thread. 
    gtk_label_set(GTK_LABEL(label1), "some state"); 
} 

// This causes draw() to be called on the graphics thread. 
gtk_please_redraw_this_thing_on_the_graphics_thread(); 

Есть ли способ сделать это? Или любые учебники, которые его охватывают?

+0

Ca вы не используете [GCD] (http://developer.apple.com/library/ios/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html): 'dispatch_async (dispatch_get_main_queue(), ...) '? –

+0

Я стараюсь сделать его как можно более переносимым, поэтому предпочли бы не полагаться на функцию Mac OS X. – DanielGibbs

ответ

1

Оказывается, это довольно просто.

Сначала нужно создать функцию, которая будет делать чертеж (на графическом потоке):

gboolean draw_function(GtkWidget *w, GdkEventExpose *event) { 
    // Draw things. 
    return TRUE; 
} 

Затем, во время установки, подключите draw событие виджета для вашей функции рисования:

g_signal_connect(G_OBJECT(some_widget), "draw", G_CALLBACK(draw_function), NULL); 

Наконец, чтобы заставить виджет перерисовывать из другого потока можно назвать:

gtk_widget_queue_draw(some_widget); 
Смежные вопросы