【发布时间】:2014-12-18 20:25:41
【问题描述】:
我正在尝试使用 Gtk 3.0 实时可视化节点网络。节点网络将产生新节点,并且节点之间将实时形成新的连接。我正在考虑使用一个线程来配置 Gtk 并开始 Gtk 的主循环,另一个用于节点网络的开发。网络的变量将是全局的,因此网络开发线程和 Gtk 线程都可以看到网络变量。我会在两边使用互斥锁来确保同步。
我的 Gtk 事件处理函数将绘制当前网络,理想情况下,它应该在每次网络变化(例如新节点、新连接)时被调用。因此,我想知道 Gtk 3.0 中是否有解决方案,每次变量更改时都会发出事件处理函数的信号,比如向量大小的变化,因为我使用向量来存储节点和连接。
我编写了一个简单的测试程序,只是为了看看我想要做的事情是否可行。我有一个线程不断增加一个整数,而另一个线程执行所有 Gtk 配置并启动主循环。在下面的这段代码中,Gtk 线程绘制了不断递增的整数的当前值。但是,此代码是对另一个代码的修改,它仅在值更改时才绘制当前值。此外,此代码无法在 Gtk 3.0 中编译。有没有办法让这段代码在 Gtk 3.0 中编译?另外,是否可以让它只在整数值发生变化时才向绘图函数发出信号?
#include <gtk/gtk.h>
#include <math.h>
#include <thread>
#include <mutex>
#include <string>
unsigned long long counter;
std::mutex mtx;
gboolean timeout(gpointer data) {
GtkWidget *widget = GTK_WIDGET(data);
if (!widget->window) return TRUE;
gtk_widget_queue_draw(widget);
}
gboolean expose(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
cairo_t *cr = gdk_cairo_create(widget->window);
cairo_rectangle(cr, event->area.x, event->area.y, event->area.width, event- >area.height);
cairo_clip(cr);
cairo_set_source_rgb(cr, 0.1, 0.1, 0.1);
cairo_select_font_face(cr, "Purisa", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
std::string str;
mtx.lock();
str = std::to_string(counter);
cairo_move_to(cr, 20, 30);
cairo_show_text(cr, str.c_str());
mtx.unlock();
return FALSE;
}
void setupGtk() {
gtk_init(NULL,NULL);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(GTK_WINDOW(window), "destroy",G_CALLBACK(gtk_main_quit), NULL);
GtkWidget *drawing_area = gtk_drawing_area_new();
g_signal_connect(drawing_area,"expose_event",G_CALLBACK(expose),NULL);
gtk_container_add(GTK_CONTAINER(window), drawing_area);
gtk_widget_show(drawing_area);
g_timeout_add(10, timeout, window);
if (!GTK_WIDGET_VISIBLE (window))
gtk_widget_show_all(window);
else {
gtk_widget_destroy (window);
window = NULL;
}
gtk_main();
}
void count() {
while(counter<100000000) {
mtx.lock();
counter++;
mtx.unlock();
}
}
int main(int argc, char *argv[]) {
std::thread gtk(setupGtk);
std::thread process(count);
gtk.join();
process.join();
return 1;
}
【问题讨论】: