6

Gtkの他のビットについての私の理解をテストするために、メインループが消費する準備ができているイベントを常に持っているプログラムを書きたいと思います。私はこれを試すためにこの短いプログラムを書きました:

#include <gtk/gtk.h>

static void toggle(GtkWidget *check, gpointer data)
{
    gboolean checked;
    g_object_get(check, "active", &checked, NULL);
    g_object_set(check, "active", !checked, NULL);
}

int main(int argc, char *argv[])
{
    GtkWidget *window, *check;
    gtk_init(&argc, &argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    check  = gtk_check_button_new();
    g_signal_connect(check, "toggled", G_CALLBACK(toggle), NULL);
    gtk_container_add(GTK_CONTAINER(window), check);
    gtk_widget_show_all(window);
    gtk_main();
}

このプログラムを実行してチェックボックスをクリックすると、セグフォールトが発生します。何が得られますか?メインループをビジー状態に保つ正しい方法は何ですか?

(補足:segfaultingの前に2048回確実にトグルします-疑わしいラウンド数です。)

4

1 に答える 1

7

ハンドラー内でtoggle、を設定します。checkedこれにより、toggleシグナルが発行され、ハンドラーが再度呼び出されます。

#11564 0xb775ba50 in g_closure_invoke () from /usr/lib/libgobject-2.0.so.0
#11565 0xb776e5d0 in ?? () from /usr/lib/libgobject-2.0.so.0
#11566 0xb77774d6 in g_signal_emit_valist () from /usr/lib/libgobject-2.0.so.0
#11567 0xb7777682 in g_signal_emit () from /usr/lib/libgobject-2.0.so.0
#11568 0xb7e067ba in gtk_toggle_button_toggled ()

完全には追跡しませんでしたが、11000フレームを超えるとセグメンテーション違反が発生することがわかります。

あなたの他の質問に答えるために:私はメインループをいっぱいに保つ方法はg_idle_add()電話であると思います:

#include <gtk/gtk.h>

static void toggle(GtkWidget *check, gpointer data)
{
  g_print(".");
}

GtkWidget *window, *check;

static gboolean
toggle_it()
{
  gboolean checked;
  g_object_get(check, "active", &checked, NULL);
  g_object_set(check, "active", !checked, NULL);
  return TRUE;
}

int main(int argc, char *argv[])
{
    gtk_init(&argc, &argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    check  = gtk_check_button_new();
    g_signal_connect(check, "toggled", G_CALLBACK(toggle), NULL);
    gtk_container_add(GTK_CONTAINER(window), check);
    gtk_widget_show_all(window);
    g_idle_add((GSourceFunc)toggle_it, NULL);
    gtk_main();
}
于 2012-06-01T22:01:46.583 に答える