2013-03-22 59 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);