如何从gtk widget访问'gseal'ed值修改GtkWidgets

时间:2013-03-22 11:58:35

标签: c gtk

GTK使用GSEAL选项来阻止某人访问Widget-struct。 这很好,因为 C 中的客观编程你应该像其他语言一样使用get-functions。

由于GtkButton的每个值都没有get函数,因此我在修改自己的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

3 个答案:

答案 0 :(得分:3)

您从未被视为访问GtkButton实例结构中的那些字段:它们是私有的,并且仅供内部使用(之所以它们不像现代GTK代码那样真正私有,是因为{{ 1}}在我们可以在GtkButton内添加实例私有数据之前很久就存在了 - 长篇故事。)

GObject信号标记为GtkButton::clicked,这意味着与该类关联的默认信号处理程序在使用RUN_FIRST附加的任何回调之前运行。

如果你想阻止发出g_signal_connect()信号(无论如何都不是一个好主意)你可以使用信号发射钩子,或者你可以继承GtkButton::clicked并停止从默认处理程序中发出的信号。

答案 1 :(得分:0)

你应该从不访问这样的成员变量。的 EVER 即可。这些是私有变量。这就是为什么推出GSeal的原因。您的代码可能会因GTK +

的更新而中断

答案 2 :(得分: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);