GTK+. Создание собственного виджета?.. (разбираюсь с основами)

Модератор: Модераторы разделов

CPU
Сообщения: 41
ОС: Fedora Core 6 x86_64

GTK+. Создание собственного виджета?..

Сообщение CPU »

Разбираюсь с созданием собственных виджетов на GTK+. На руках только примерчик с gtk.org..
Собственно, первичная цель проста - сделать виджет MyButton, отличающий от обычного GtkButton только тем, что при создании у MyButton сразу будет вбита некоторая надпись (label).
С горем пополам были созданы такие строчки:

Код: Выделить всё

//////// MYBUTTON.H /////////
...
typedef struct _MyButton       MyButton;
typedef struct _MyButtonClass  MyButtonClass;

struct _MyButton
{
    GtkButton button;
};

struct _MyButtonClass
{
  GtkButtonClass parent_class;

};
.....

///// MYBUTTON.CPP ////////
#include <gtk/gtkbutton.h>
#include "mybutton.h"

static void mybutton_class_init          (MyButtonClass *klass);
static void mybutton_init                (MyButton      *btn);

GType
mybutton_get_type (void)
{
  static GType ttt_type = 0;

  if (!ttt_type)
    {
      static const GTypeInfo ttt_info =
      {
          sizeof (MyButtonClass),
              NULL, /* base_init */
          NULL, /* base_finalize */
          (GClassInitFunc) mybutton_class_init,
          NULL, /* class_finalize */
          NULL, /* class_data */
          sizeof (MyButton),
          0,
          (GInstanceInitFunc) mybutton_init,
      };

      ttt_type = g_type_register_static (GTK_TYPE_BUTTON, "MyButton", &ttt_info, (GTypeFlags)0);
    }

  return ttt_type;
}

static void
mybutton_class_init (MyButtonClass *klass)
{
}

static void
mybutton_init (MyButton *btn)
{

}

GtkWidget*
mybutton_new ()
{
  return GTK_WIDGET (g_object_new (mybutton_get_type (), "label", "My super-super button!", NULL));
}


Все работает, но хотелось бы перенести назначение надписи в ф-цию mybutton_init(). имхо, это логичнее.
Однако, вот такой код:

Код: Выделить всё

..
static void
mybutton_init (MyButton *btn)
{
    gtk_button_set_label(GTK_BUTTON(btn), "My super-super button!");
}

GtkWidget*
mybutton_new ()
{
    return GTK_WIDGET (g_object_new (mybutton_get_type (), NULL));
}
..


создает кнопку вообще без подписи. В чем ошибочность такого варианта? И как исправить это дело?


З.Ы. В приложенном архиве исходный код целиком с тем самым "проблемным" вариантом, который создает кнопку без подписи.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Спасибо сказали:
sergio
Сообщения: 436
Статус: Интересующийся новичок
ОС: Debian GNU/Linux 4 & 5

Re: GTK+. Создание собственного виджета?..

Сообщение sergio »

.
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Спасибо сказали:
Аватара пользователя
sergeyvp
Сообщения: 807
ОС: ubuntu

Re: GTK+. Создание собственного виджета?..

Сообщение sergeyvp »

Вот хороший пример создания собственного виджета
http://www.sib.opennet.ru/gtkcario/gtkwcario.html
http://www.sib.opennet.ru/gtkcario/gtkcairo2.html

Остальное можно найти на моём сайте, я во всех тонкостях пока ещё сам не разобрался :)
Спасибо сказали:
Аватара пользователя
sergeyvp
Сообщения: 807
ОС: ubuntu

Re: GTK+. Создание собственного виджета?..

Сообщение sergeyvp »

Чуть не забыл, по поводу вашего примера.
Не работает видимо потомучто при установке текста виджет не получает сигнал на перерисовку, то есть свойство установлено но внешний вид не обновлён. (хотя конечно могу и ошибиться) В приведённом мной примере есть функция отвечающая за перерисовку egg_clock_face_redraw_canvas(), возможно в ней всё дело :)
Спасибо сказали:
CPU
Сообщения: 41
ОС: Fedora Core 6 x86_64

Re: GTK+. Создание собственного виджета?..

Сообщение CPU »

sergeyvp писал(а):
29.10.2007 01:01
Чуть не забыл, по поводу вашего примера.
Не работает видимо потомучто при установке текста виджет не получает сигнал на перерисовку, то есть свойство установлено но внешний вид не обновлён. (хотя конечно могу и ошибиться) В приведённом мной примере есть функция отвечающая за перерисовку egg_clock_face_redraw_canvas(), возможно в ней всё дело :)


Я думаю, дело немного в другом.. Почитав документацию, а также порывшись в исходниках glib, я выяснил, что функция g_object_new() инициирует все поля объекта. Причем, если в нее не передаешь пару "поле/значение", то данное поле забивается значением по умолчанию. А для строк (коей и является подпись на кнопке) дефолтное значение - пустая строка. Вот и приехали.

Это, кстати, и подтверждается во время пошаговой отладки моего примера. То есть во время mybutton_init() назначается поле "label", но потом вызывается g_object_new() и перетирает это поле.
Спасибо сказали:
Аватара пользователя
sergeyvp
Сообщения: 807
ОС: ubuntu

Re: GTK+. Создание собственного виджета?..

Сообщение sergeyvp »

CPU писал(а):
30.10.2007 23:29
Это, кстати, и подтверждается во время пошаговой отладки моего примера. То есть во время mybutton_init() назначается поле "label", но потом вызывается g_object_new() и перетирает это поле.

Ну может быть, хотя странно всё это.
Я думал что g_object_new() вызывается для создания объекта а _init() инициализирует его значениями, а судя по тому что вы описали g_object_new() вызывается два раза. Странно вобщем.
Спасибо сказали:
Аватара пользователя
sergeyvp
Сообщения: 807
ОС: ubuntu

Re: GTK+. Создание собственного виджета?..

Сообщение sergeyvp »

Сейчас ради интереса на своём объекте проверил последовательность вызовов
Вот что получилось
Первый раз создаётся объект
_new
class_init
_init
Второй раз создаётся объект
_new
_init
так что не может _new переписать значения установленные _init
Спасибо сказали:
CPU
Сообщения: 41
ОС: Fedora Core 6 x86_64

Re: GTK+. Создание собственного виджета?..

Сообщение CPU »

sergeyvp писал(а):
30.10.2007 23:58
Сейчас ради интереса на своём объекте проверил последовательность вызовов
Вот что получилось
Первый раз создаётся объект
_new
class_init
_init
Второй раз создаётся объект
_new
_init
так что не может _new переписать значения установленные _init


наверное, я где-то ошибся и сделал поспешный вывод.. Буду разбираться..
Спасибо сказали:
TwisT
Сообщения: 265
ОС: Debian

Re: GTK+. Создание собственного виджета?..

Сообщение TwisT »

ОФФТОП:
не ребята, ну честно, смотрю на вас и плакать хочется. Это ж скоко нужно сделать лишних движений что бы получить всего на всего
пимпочку с текстом, бросайте это гнилое дело, уже 20 лет прошло с того момента когда люди придумали ООП и успешно его пользуют
скоко всего вокруг
Linux user #432536.
Спасибо сказали:
CPU
Сообщения: 41
ОС: Fedora Core 6 x86_64

Re: GTK+. Создание собственного виджета?..

Сообщение CPU »

sergeyvp писал(а):
30.10.2007 23:58
Сейчас ради интереса на своём объекте проверил последовательность вызовов
Вот что получилось
Первый раз создаётся объект
_new
class_init
_init
Второй раз создаётся объект
_new
_init
так что не может _new переписать значения установленные _init


Здесь под _new имеется ввиду _new нового класса? То есть в моем примере, я так понимаю, это mybutton_new()?
Тогда я не спорю - последовательность вызова именно такая. Я говорил о том, что g_object_new(), который у меня вызывается внутри mybutton_new() перетирает поле "label" (предположительно)

[offtop]
ко мне можно на "ты". мне кажется, это удобнее..
[offtop]

TwisT писал(а):
31.10.2007 00:03
ОФФТОП:
не ребята, ну честно, смотрю на вас и плакать хочется. Это ж скоко нужно сделать лишних движений что бы получить всего на всего
пимпочку с текстом, бросайте это гнилое дело, уже 20 лет прошло с того момента когда люди придумали ООП и успешно его пользуют
скоко всего вокруг


Тут главное понять принцип. А дальше, смею надеяться, особых "лишних движений" не будет :)
Спасибо сказали:
sergio
Сообщения: 436
Статус: Интересующийся новичок
ОС: Debian GNU/Linux 4 & 5

Re: GTK+. Создание собственного виджета?..

Сообщение sergio »

TwisT писал(а):
31.10.2007 00:03
ОФФТОП:
не ребята, ну честно, смотрю на вас и плакать хочется. Это ж скоко нужно сделать лишних движений что бы получить всего на всего
пимпочку с текстом, бросайте это гнилое дело, уже 20 лет прошло с того момента когда люди придумали ООП и успешно его пользуют
скоко всего вокруг

Для товащей несведущих, но с гонором: то, что в этой ветке обсуждается - это ООП. Конкретнее здесь обсуждается наследование, создание класса-наследника. Если вы используете ООП и при это не знаете, что такое ООП - это ваша беда. :happy:
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Спасибо сказали:
Аватара пользователя
sergeyvp
Сообщения: 807
ОС: ubuntu

Re: GTK+. Создание собственного виджета?..

Сообщение sergeyvp »

TwisT писал(а):
31.10.2007 00:03
ОФФТОП:
не ребята, ну честно, смотрю на вас и плакать хочется. Это ж скоко нужно сделать лишних движений что бы получить всего на всего
пимпочку с текстом, бросайте это гнилое дело, уже 20 лет прошло с того момента когда люди придумали ООП и успешно его пользуют
скоко всего вокруг

Это примерно тоже самое как если бы сюда зашёл простой пользователь и сказал:
"Смотрю я на вас и плакать хочется. Все программы уже давно написала МС и они успешно используются, бросайте это гнилое дело, айда пиво пить"

ООП по вашему кто придумал? А как они это сделали? А усовершенствования существующих языков и программ как происходит?
Я вот сейчас как раз пишу программу на Си и поверьте мне наслушался высказываний подобных вашему вдоволь :)
Вот только чтобы стать нормальным программистом нужно всё таки в основах разбираться, что откуда и куда, а Си -- это основа основ практически.
Всё сказанное естественно ИМХО.
Спасибо сказали:
Аватара пользователя
sergeyvp
Сообщения: 807
ОС: ubuntu

Re: GTK+. Создание собственного виджета?..

Сообщение sergeyvp »

У вас в заголовочном файле отсутсвуют вот такие строки

#define EGG_TYPE_CLOCK_FACE (egg_clock_face_get_type ())
#define EGG_CLOCK_FACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_CLOCK_FACE, EggClockFace))
#define EGG_CLOCK_FACE_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), EGG_CLOCK_FACE, EggClockFaceClass))
#define EGG_IS_CLOCK_FACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_CLOCK_FACE))
#define EGG_IS_CLOCK_FACE_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((obj), EGG_TYPE_CLOCK_FACE))
#define EGG_CLOCK_FACE_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_CLOCK_FACE, EggClockFaceClass))

Видимо поэтому все грабли.
Посмотрите тот пример ссылки на который я дал.

P/S Я тут со всеми на ВЫ, так молодежь меньше безобразничает, видит что взрослые дядьки общаются :D
Спасибо сказали:
CPU
Сообщения: 41
ОС: Fedora Core 6 x86_64

Re: GTK+. Создание собственного виджета?..

Сообщение CPU »

sergeyvp писал(а):
31.10.2007 00:30
У вас в заголовочном файле отсутсвуют вот такие строки

#define EGG_TYPE_CLOCK_FACE (egg_clock_face_get_type ())
#define EGG_CLOCK_FACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_CLOCK_FACE, EggClockFace))
#define EGG_CLOCK_FACE_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), EGG_CLOCK_FACE, EggClockFaceClass))
#define EGG_IS_CLOCK_FACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_CLOCK_FACE))
#define EGG_IS_CLOCK_FACE_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((obj), EGG_TYPE_CLOCK_FACE))
#define EGG_CLOCK_FACE_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_CLOCK_FACE, EggClockFaceClass))

Видимо поэтому все грабли.
Посмотрите тот пример ссылки на который я дал.


Нет-нет.. У меня есть аналогичные строки.
Их можно увидеть, скачав архив. Я просто не посчитал это важным для моего вопроса - вот и не процитировал.
А на самом деле, там вот что:

Код: Выделить всё

#define MYBUTTON_TYPE            (mybutton_get_type ())
#define MYBUTTON(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), MYBUTTON_TYPE, MyButton))
#define MYBUTTON_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), MYBUTTON_TYPE, MyButtonClass))
#define IS_MYBUTTON(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MYBUTTON_TYPE))
#define IS_MYBUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MYBUTTON_TYPE))

То есть разница всего лишь в одну строчку. У меня нет аналога вот этого:

Код: Выделить всё

 #define EGG_CLOCK_FACE_GET_CLASS        (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_CLOCK_FACE, EggClockFaceClass))


Впрочем, как я только что проверил, добавив такую строку, это не помогает :(

sergeyvp писал(а):
31.10.2007 00:30
P/S Я тут со всеми на ВЫ, так молодежь меньше безобразничает, видит что взрослые дядьки общаются :D


Принято к сведению :)
Спасибо сказали: