2013-03-22 42 views
0

GTK使用GSEAL選項來阻止某些人訪問Widget-struct。 這很好,因爲在C中的客觀編程,你應該使用像其他語言一樣的get函數。如何從gtk小部件訪問'gseal'值|修改GtkWidgets

由於GtkButton的每個值都沒有獲得函數,所以在修改我自己的GtkWidgets時遇到了一些問題。

我希望獲得這些值struct _GtkButton

struct _GtkButton 
{ 
    .... 
    guint GSEAL (activate_timeout); 
    guint GSEAL (in_button) : 1; 
    guint GSEAL (button_down) : 1; 
    .... 
} 

我想補充一個on-click事件mybutton,取消單擊事件他們將被調用之前,所以我決定重新實現:

static void gtk_real_button_pressed(GtkButton *button) 
{ 
    if (button->activate_timeout) 
     return; 

    button->button_down = TRUE; 
    gtk_button_update_state(button); 
} 

static void gtk_real_button_released(GtkButton *button) 
{ 
    if (button->button_down) 
    { 
     button->button_down = FALSE; 

     if (button->activate_timeout) 
      return; 

     if (button->in_button) 
     { 
      // do my own stuff here and maybe don'tcall "gtk_button_clicked(...)" 
      gtk_button_clicked(button); 
     }  
     gtk_button_update_state(button); 
    } 
} 

正如我在頂部所說的,我現在需要訪問button->in_button例如。任何人都有線索,可以幫助我嗎? :)


的方式:

guint GSEAL (button_down) : 1; 

我想不出什麼在這種情況下使用: 1。 :O

+0

剛發現一個解決方案。我會在6個小時內發佈它,因爲我有10個聲望:O xD – 2013-03-22 13:48:04

+1

「:1」意味着只有一個類型的位將被使用,編譯器應該嘗試更緊密地打包結構儘可能。 – ebassi 2013-03-22 14:29:17

+0

thx的信息, 實際上通過挖掘debuger中的內存找到了自己:) – 2013-03-22 14:57:22

回答

3

你從來沒有被認爲進入這些領域的GtkButton實例結構:他們是私有的,只能用於內部使用(他們爲什麼沒有真正的私人像現代GTK的原因代碼是因爲GtkButton存在很久之前我們可以在GObject - 長篇故事裏添加實例私人數據)。

GtkButton::clicked信號標在RUN_FIRST,這意味着使用任何g_signal_connect()回調附着之前相關聯的類的默認的信號處理程序開始運行。

如果您想防止發射信號(這不是一個好主意,無論如何),您可以使用信號發射掛鉤,或者您可以繼承GtkButton並將信號發射從默認值處理程序。

+0

我使用GTK 2 我已經子類的Gtk按鈕現在,擡頭GTK的源代碼重寫「real_button_press」,並以explan自己「real_button_release」 – 2013-03-22 15:06:28

+0

:我在寫書面方式面板,應該進入編輯模式如果我按住一個按鈕約5秒鐘。 在編輯模式下,我的所有按鈕都不應引發其單擊事件。 而不是使用布爾值我想要一個「點擊」事件並返回一個'中止信號',如果我需要它。 – 2013-03-22 15:17:41

0

您應該從不訪問像這樣的成員變量。 EVER。這些是私有變量。這就是GSeal被引入的原因。您的代碼可能打破更新GTK +

+0

我真的知道這一點,但爲了寫我自己的小部件,我不得不覆蓋父母的一些功能。在這種情況下是「GtkButton」。 我必須使用gtk 2.10,因爲我使用了arm控制器和交叉編譯器。 所以在我的情況下,gtk不會被更新!如果是這樣,我的小部件也應該更新。 我擡頭看了一眼「gtkbutton.c」,只爲我的需要重寫了一下,而不是改變gtkbutton.c。 – 2013-03-22 15:12:09

+0

如果你需要這樣做,那麼你做錯了。 Ebassi告訴你正確的方式去做你想做的事。 (反正Gtk2.10並沒有使用GSeal。) – iain 2013-03-22 15:17:29

+0

這是我第一個想法,來實現我的需求。 未找到其他方法:/ btw:剛剛看到我在手臂上使用gtk 2.10,在我的電腦上使用2.24。 你的權利,2.10不使用GSEAL。我期待着找到另一種解決方案,就像ebassi說的那樣。 – 2013-03-22 15:29:46

0

我現在使用這個小函數,使用gseal值是真的沒有我應該做的。

typedef struct _GuiOnClickHandler GuiOnClickHandler; 
struct _GuiOnClickHandler 
{ 
    gboolean abortClick; 

}; 

static void gui_recipe_button_clicked(GtkWidget *widget, gpointer data) 
{ 
    GuiOnClickHandler handler; 
    handler.abortClick = FALSE; 

    g_signal_emit_by_name((gpointer)widget, "on-click", &handler); 

    if (handler.abortClick) 
     g_signal_stop_emission_by_name((gpointer)widget, "clicked"); 
} 

...somewhere else on init, at first place 

    g_signal_connect(GTK_OBJECT (button), "clicked", 
      G_CALLBACK (gui_recipe_button_clicked), NULL);