Существует ли хороший способ скопировать виджет Gtk?

Есть ли путь, пользуясь библиотекой Gtk в C, чтобы клонировать кнопку Gtk (например), и упаковать его где-то в другом месте в приложении. Я знаю, что Вы не можете упаковать тот же виджет дважды. И что этот код, очевидно, не работал бы, но шоу, что происходит, когда я делаю попытку мелкой копии кнопки:

GtkButton *a = g_object_new(GTK_TYPE_BUTTON, "label", "o_0", NULL);
GtkButton *b = g_memdup(a, sizeof *a);
gtk_box_pack_start_defaults(GTK_BOX(vbox), GTK_WIDGET(b));

Там окружает код, который создает vbox и упаковывает его в окне и выполняет gtk_main (). Это приведет к ним трудно для понимания сообщений об ошибках:

(main:6044): Gtk-CRITICAL **: gtk_widget_hide: assertion `GTK_IS_WIDGET (widget)' failed

(main:6044): Gtk-CRITICAL **: gtk_widget_realize: assertion `GTK_WIDGET_ANCHORED (widget) || GTK_IS_INVISIBLE (widget)' failed
**
Gtk:ERROR:/build/buildd/gtk+2.0-2.18.3/gtk/gtkwidget.c:8431:gtk_widget_real_map: assertion failed: (GTK_WIDGET_REALIZED (widget))

В том же направлении, если я должен был записать свой собственный GObject (не обязательно виджет Gtk), есть ли хороший способ записать конструктору копии. Я думаю, что это должен быть интерфейс с дополнительными рычагами и базирующийся главным образом на свойствах, обработав иерархию класса в некотором роде.

Я хотел бы сделать это:

GtkButton *b = copyable_copy(COPYABLE(a));

Если GtkButton мог бы использовать теоретический copyable интерфейс.

7
задан Jake 9 June 2010 в 12:26
поделиться

2 ответа

Клонирование через свойства - жизнеспособное решение:

GObject *
g_object_clone(GObject *src)
{
    GObject *dst;
    GParameter *params;
    GParamSpec **specs;
    guint n, n_specs, n_params;

    specs = g_object_class_list_properties(G_OBJECT_GET_CLASS(src), &n_specs);
    params = g_new0(GParameter, n_specs);
    n_params = 0;

    for (n = 0; n < n_specs; ++n)
        if (strcmp(specs[n]->name, "parent") &&
            (specs[n]->flags & G_PARAM_READWRITE) == G_PARAM_READWRITE) {
            params[n_params].name = g_intern_string(specs[n]->name);
            g_value_init(&params[n_params].value, specs[n]->value_type);
            g_object_get_property(src, specs[n]->name, &params[n_params].value);
            ++ n_params;
        }

    dst = g_object_newv(G_TYPE_FROM_INSTANCE(src), n_params, params);
    g_free(specs);
    g_free(params);

    return dst;
}

Клонирование виджета не так уж и тривиально, но описанный выше подход можно использовать в большинстве случаев (на GtkButton для уверенности).

Меня не волнует, что многие состояния не отображаются с помощью свойств (все соответствующие виджеты должны быть полностью определены свойствами, чтобы их можно было использовать с GtkBuilder ), но многие угловые случаи сделают надежное клонирование довольно сложно (интерфейсы и контейнеры - первые, что приходят мне в голову).

3
ответ дан 7 December 2019 в 07:40
поделиться

Я так не думаю. Насколько мне известно, нет гарантии, что виджеты сохранят все свое состояние в свойствах, к которым вы можете получить доступ извне. Если виджет «скрывает» состояние, не экспортируя его, вы не сможете скопировать его извне.

Технически виджеты могут просто включать в свою основную структуру поля, которые вы не видите снаружи реализации, поэтому вы даже не можете скопировать биты с помощью глупой memcpy () , если вы не хотите указывать количество байтов, подсчитывая вручную и используя литерал.

При этом также вполне возможно, что достаточное количество виджетов раскрывают достаточное количество состояний через свойства, чтобы их копия продолжала работать, и, возможно, демонстрируют лишь незначительные сбои. Это, безусловно, был бы довольно крутой хакер. Я бы порекомендовал напрямую спросить у основных разработчиков GTK +, возможно, в списке рассылки gtk-devel-list .

4
ответ дан 7 December 2019 в 07:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: