0

私はGTK+を学んでいますが、この単純なアプリケーションは実行するたびにクラッシュします。

メインウィンドウにラベルが作成され、ボタンがクリックされるたびに(key_press_event)ラベルとタイトルが入れ替わります。

gtk_label_set_text関数内でコメントアウトするchange_titleと、タイトルが正しく切り替わり、アプリがクラッシュしません。gtk_label_set_textアプリがクラッシュするのはなぜですか?

#include <gtk/gtk.h>
#include <string.h>

const gchar first[]="FIRST";
const gchar last[]="LAST";

static void destroy(GtkWidget *window,gpointer data)
{
  gtk_main_quit();
}

static gboolean change_title(GtkWidget *widget,GtkLabel *data)
{
  if(strcmp(last,gtk_window_get_title(GTK_WINDOW(widget)))){
    gtk_window_set_title(GTK_WINDOW(widget),last);
    gtk_label_set_text(data,first);
  } else {
    gtk_window_set_title(GTK_WINDOW(widget),first);
    gtk_label_set_text(data,last);
  }
  return FALSE;
}

int main(int argc,char **argv)
{
  GtkWidget *window, *label;
  gtk_init(&argc,&argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(window),last);
  gtk_widget_set_size_request(window,300,100);
  g_signal_connect(window,"destroy_event",G_CALLBACK(destroy),NULL);

  label = gtk_label_new("caasdasdjadnjadjahadjad");
  gtk_container_add(GTK_CONTAINER(window),label);

  g_signal_connect(window,"key_press_event",G_CALLBACK(change_title),GTK_LABEL(label));

  gtk_widget_show_all(window);

  gtk_main();
  return 0;
}        

編集:GDBを使用して問題を発見しました。ラベル・ポインターが関数に正しく渡されませんchange_title。どうしてか分かりません。(例:main()ラベル内= 0xb6406608change_title()ラベル内= 0x807bda8

4

2 に答える 2

2

で簡単なGoogle検索を行った後、key_press_eventそのイベントへのコールバックには、ウィジェットとユーザーデータポインターの間に別の引数があることがわかりました。プロトタイプはこれです:

gboolean key_event_handler(GtkWidget *widget,GdkEventKey *event, gpointer data);

関数を次のように変更するだけです。

static gboolean change_title(GtkWidget *widget, GdkEventKey *event, GtkLabel *data)

そしてそれは動作するはずです。

于 2012-08-23T12:37:43.437 に答える
1

関数change_titleのプロトタイプが間違っています。

適切なプロトタイプについては、ドキュメントを参照してください。*-eventハンドラーは通常、実行するためにイベントを検査する必要があるため、ほとんどのシグナルはハンドラー関数の引数として実際のイベントを渡します。たとえば、ここでのGdkEventKeyイベントには、どのキーが押されたか(または離されたか)に関する情報が含まれます。

于 2012-08-23T12:38:17.603 に答える