簡體   English   中英

GTK將結構傳遞給C中的回調函數

[英]GTK passing structure to callback function in C

GTK還是一個新事物,現在正嘗試進行事件驅動的編程,並陷入了一種怪異的境地:將標量項目發送到回調函數沒有問題,但是隨后就向它發送了struct,仍然收到錯誤,卻不知道是什么錯誤。

示例“存根”代碼為:

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

void messageup();
void exiting();

struct data{
    char *message;
    GtkWidget *window;
};


int main (int   argc, char *argv[])
{
  GtkBuilder      *builder; 
  GtkWidget       *window;
  GtkWidget       *entryMainValue;
  struct data d;

  gtk_init (&argc, &argv);

  builder = gtk_builder_new ();
  gtk_builder_add_from_file (builder, "samplemain.ui", NULL);
  window = GTK_WIDGET (gtk_builder_get_object (builder, "applicationwindow1"));
  entryMainValue = GTK_WIDGET (gtk_builder_get_object (builder, "entryMainValue"));
  g_signal_connect (window, "delete_event", G_CALLBACK (exiting), NULL);
  d.message = "message\n";
  d.window = window;
  g_signal_connect (entryMainValue, "activate", G_CALLBACK (messageup), d);
  g_object_unref (G_OBJECT (builder));
  gtk_widget_show (window);                
  gtk_main ();

  return 0;
}

void messageup(GtkWidget *entryMainValue, gpointer user_data){

    struct data *d = (struct data*) user_data;


    g_print("Hello World!\n%s\n", user_data.message);
}

void exiting()
{
    exit(0);
}

現在出現如下錯誤:

gtkbldprj.c: In function ‘main’:
gtkbldprj.c:29:3: error: incompatible type for argument 4 of ‘g_signal_connect_data’
   g_signal_connect (entryMainValue, "activate", G_CALLBACK (messageup), d);
   ^
In file included from /usr/include/glib-2.0/gobject/gobject.h:28:0,
                 from /usr/include/glib-2.0/gobject/gbinding.h:29,
                 from /usr/include/glib-2.0/glib-object.h:23,
                 from /usr/include/glib-2.0/gio/gioenums.h:28,
                 from /usr/include/glib-2.0/gio/giotypes.h:28,
                 from /usr/include/glib-2.0/gio/gio.h:26,
                 from /usr/include/gtk-3.0/gdk/gdkapplaunchcontext.h:28,
                 from /usr/include/gtk-3.0/gdk/gdk.h:32,
                 from /usr/include/gtk-3.0/gtk/gtk.h:30,
                 from gtkbldprj.c:1:
/usr/include/glib-2.0/gobject/gsignal.h:388:9: note: expected ‘gpointer’ but argument is of type ‘struct data’
 gulong  g_signal_connect_data        (gpointer    instance,
         ^
gtkbldprj.c: In function ‘messageup’:
gtkbldprj.c:42:41: error: request for member ‘message’ in something not a structure or union
  g_print("Hello World!\n%s\n", user_data.message);
                                         ^
gtkbldprj.c:39:15: warning: unused variable ‘d’ [-Wunused-variable]
  struct data *d = (struct data*) user_data;

任何幫助將不勝感激!

這里有幾個C錯誤。 GTK允許您在某些函數上傳遞gpointer user_data gpointer只是一個void * (即指向某物的指針)。 如果要傳遞結構,則需要結構的地址,而不是結構本身。 這稱為按地址傳遞 ,而不是按值傳遞

因此,代替:

g_signal_connect (entryMainValue, "activate", G_CALLBACK (messageup), d);

寫:

g_signal_connect (entryMainValue, "activate", G_CALLBACK (messageup), &d);

然后,當您處於回調中時,收到的user_data參數是指向something的指針。 您需要將其轉換為指向您的結構的指針。

所以代替:

void messageup(GtkWidget *entryMainValue, gpointer user_data)
{
    struct data *d = (struct data*) user_data;
    g_print("Hello World!\n%s\n", user_data.message);
}

您需要使用正確類型的指針( d ,而不是user_data )訪問消息字段,並在通過指針訪問結構時使用->運算符:

void messageup(GtkWidget *entryMainValue, gpointer user_data)
{
    struct data *d = user_data;
    g_print("Hello World!\n%s\n", d->message);
}

您似乎對指針感到困惑,因此請看一下有關C指針的視頻

另一個錯誤是連接到delete-event退出。 此事件是在您要捕獲用戶單擊窗口的出口十字或使用Alt-F4退出的事實,並且此時您想要執行某項操作(顯示確認彈出窗口,保存一些數據)時。 因此,無需在那里連接,將發生銷毀(使用destroy信號)。

因此, 不要連接到delete-event信號, 而是連接到destroy信號,並響應該信號,退出GTK +主循環:

g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM