LINUX.ORG.RU
ФорумTalks

GTK facepalm

 ,


0

2

Добры молодцы из команды GTK навертали чертову уйму классов для отделения логики от интерфейса. Все эти GtkAction, GtkUiManager, GtkActivatable и прочие упоительные названия.

У GtkAction есть имя, иконка, тултип, состояния sensetive и visible. На их основе генерируется внешний вид и состояния менюшечек и тулбаров. Короче, всё как у взрослых.

Почти. Если не считать того досадного факта, что тултип абсолютно бесполезен, т.к. не используется при создании меню.

Ладно. Решаю по-быстрому накалякать пару костылей — у нас же ООП, реюз кода во все поля и всё такое прочее. Мы можем переопределять поведение объектов и разводить руками тучи.

GtkImageMenuItem реализует интерфейс GtkActivatable и через него получает апдейты состояния. Ок, унаследуем свой класс от GtkImageMenuItem и допишем нужный код по установке тултипа.

GtkAction рожает из себя менюшки на основе класса, указанного в одном из полей своего класса. Ок, унаследуем свой класс от GtkAction и переопределим поле, засунув туда собственный класс менюитема.

Всё красиво, всё поООПшному, архитектурные космонавты в восторге.

Стоп. Про что-то мы забыли. А кто создаёт GtkAction-ы? GtkAction-ы создаёт GtkActionGroup. Открываем код. Смотрим. Еще раз смотрим. Хлопаем глазами и не верим в то, что видим:

void
gtk_action_group_add_actions_full (GtkActionGroup       *action_group,
				   const GtkActionEntry *entries,
				   guint                 n_entries,
				   gpointer              user_data,
				   GDestroyNotify        destroy)
{

  /* Keep this in sync with the other 
   * gtk_action_group_add_..._actions_full() functions.
   */
  guint i;
  SharedData *shared_data;

  g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));

  shared_data = g_slice_new0 (SharedData);
  shared_data->ref_count = 1;
  shared_data->data = user_data;
  shared_data->destroy = destroy;

  for (i = 0; i < n_entries; i++)
    {
      GtkAction *action;
      const gchar *label;
      const gchar *tooltip;

      if (!check_unique_action (action_group, entries[i].name))
        continue;

      label = gtk_action_group_translate_string (action_group, entries[i].label);
      tooltip = gtk_action_group_translate_string (action_group, entries[i].tooltip);

      action = gtk_action_new (entries[i].name,
			       label,
			       tooltip,
			       NULL);

Даааа, дааа, да! Развесистое дерево наследований. Абстрактные интерфейсы. Переменные класса. Фантастика на грани техники. Чертова уйма overengineered кода, который абсолютно бесполезен, потому что в итоге всё равно вся эта развесистая космическая архитектура запинается о вовремя подставленный gtk_action_new(), падает и разбивается к едреней фене. И хоронит под собой все ваши иллюзии, будто ООП волшебным образом превращает всех плохих программистов в хороших. Enjoy your code reuse.

А, да: баг репортить не буду. Если кому надо, репортите сами. Я ж обещал, что к разработке стека гномобиблиотек и пальцем не притронусь, даже на уровне отсылки багов. Лучше пойду придумаю обычный костыль с ручным назначением тултипов, без всей этой архитектурной космонавтики.

а чего еще ожидать от наркоманов, пишущих псевдоООП на сишечке

nu11 ★★★★★
()

А гтк или гном будут на Vala переписывать? Зачем они его тогда придумали? :3

Ok
()
Ответ на: комментарий от Ok

А разве гном не переписывают на него? Я не слежу за ними, но мне казалось, что в сорцах того же наутилуса уйма .vala-файлов. Лень качать, чтоб проверить.

geekless ★★
() автор топика

Лучше бы, конечно, для таких штук завести ЖЖ... Здесь все-таки больше форум, а не соцсеть.

Jayrome ★★★★★
()
Ответ на: комментарий от geekless

Да? Хм. Я думал на вале только YOBA Inc. пишет свои поделки (shotwell, какой-то мейл-клиент, который ничего не умеет).

Ok
()

навертали чертову уйму классов
дерево наследований. Абстрактные интерфейсы

Обождите, я похоже не в теме. Это что получается, в Цэ уже́ появились классы и прочие ООП-приблуды?

CARS ★★★★
()
Ответ на: комментарий от geekless

Кстати, если ты перепишешь свою lxpanelx на Qt, я, наверное, ею даже пользоваться буду.

Kindly_Cat
()
Ответ на: комментарий от CARS

Кресты были для них плохи, поэтому они переизобрели кресты на сях при помощи макросов, скотча и такой-то матери.

В общем, очень логичные ребята, ага.

geekless ★★
() автор топика
Ответ на: комментарий от CARS

То, что в крестах выглядит как

class MyClass : public BaseClass { } ;
в gtk выглядит как 2 страницы кода.

geekless ★★
() автор топика
Ответ на: комментарий от Vovka-Korovka

Хм. Глянул на git.gnome.org gedit, mutter и gnome-panel. Везде только сишечка. Получается, они сами не используют свой язык... Мда.

geekless ★★
() автор топика

Ты еще Swing не видел. И уж точно SWT не видел. А Qt - вообще загадочен

vertexua ★★★★★
()
Последнее исправление: vertexua (всего исправлений: 2)
Ответ на: комментарий от geekless

Мне эта мысль всё чаще приходит в голову.

а ты на 100% уверен, что в Qt нет идентичной проблемы? вместо gtk_action_new будет что-нибудь вроде new QtAction, а результат тот же.

waker ★★★★★
()
Ответ на: комментарий от waker

а ты на 100% уверен, что в Qt нет идентичной проблемы?

А это как раз вторая мысль, которая меня останавливает. Уверен, что костылей там не меньше.

geekless ★★
() автор топика
Ответ на: комментарий от waker

напиши свой my_action_group_add_actions_full

Это не поможет, gtk_action_group_add_actions_full дергает кишки реализации класса.

geekless ★★
() автор топика
Ответ на: комментарий от ckotinko

ты хотел спросить, почему ты написал свой объект а gtk про него не знает?

У них хватило ума правильно сделать GtkAction, в который не вхардкожены «свои» классы. Но не хватило ума сделать аналогично в GtkActionGroup. Задачи там полностью идентичны — нужно создавать экземпляры «какого-то» класса.

geekless ★★
() автор топика
Последнее исправление: geekless (всего исправлений: 1)

меня всё чаще посещают аналогичные мысли когда вижу чужой код. Я уже год сдерживаюсь чтобы не создавать нытик-тред...

true_admin ★★★★★
()
Ответ на: комментарий от geekless

Костыли там вроде бы где-то есть, но Qt4 всё-таки очень хорошо задизайнили. Так что - меньше, честное пионерское.

quiet_readonly ★★★★
()
Ответ на: комментарий от geekless

А это как раз вторая мысль, которая меня останавливает. Уверен, что костылей там не меньше.

…что, тем не менее, не помешало кдешникам насовать кучу доп.свойств в тот же qaction.

А вообще, какой смысл тут гадать? Изучи и попробуй сам!

AX ★★★★★
()

«GTK – это робот, сваренный из металлолома с ближайшей свалки. Причем, про пульт управления позабыли полностью, и управлять им можно, только замыкая оголенные проводки и дергая вручную нужные тросики. GTK – это набор принципов, найденных на свалке истории. Это нагромождение тысяч функций неизвестного назначения и происхождения. Это огромный и неповоротливый gobject, который писали пьяные марсиане. Это отсутствие интереса со стороны даже самих разработчиков, потому что им нужно „просто писать софт“, а не разбираться в работе этого нагромождения кода, дабы что-то исправить и не сломать тысячи приложений. Это криворукие программеры, неспособные даже укомплектовать свое поделие нужными библиотеками. Это бесконечные лозунги и обещания. Это то, от чего мы бежали, но к чему вернулись.

Профессиональный программист на GTK – это как профессиональный разжигатель огня при помощи кремня и трута: ужасно гордый оттого, что он умеет пользоваться такими нетривиальными приборами, а другие не умеют, потому что пользуются спичками и зажигалками.»

(c), кажется, Матвей Кожев

stevejobs ★★★★☆
()

На Qt всё куда адекватнее выглядит.(Хотя изучал быстро код на практике, исправлял чужую гуевину)

ЗЫ. Хоть уже 2 года пишу всякие штуковины на python, так и не проникся всем этим ООП.(привычка от С, когда писал для МК)

sol13 ★★★★★
()
Последнее исправление: sol13 (всего исправлений: 1)

Попробуй IUP, если не нужно сильно сложных интерфейсов или создание кастомных виджетов. Хорошая штука, есть врапперы для гкт, мотифа и для апи оффтопика.

rikardoac
()
Ответ на: комментарий от stevejobs

жаль что альтернативу этот Кожев не предложил :)

waker ★★★★★
()
Ответ на: комментарий от rikardoac

К сожалению, мне надо коммитить во вполне конкретные проекты, реализованные на gtk, так что смена тулкита не вариант. Но на будущее учту, спасибо. Потыкаю эту библиотеку при случае.

geekless ★★
() автор топика
Ответ на: комментарий от Deleted

Кстати, расскажи-ка мне, как в крестах создать экземпляр «какого-то» класса. Эта проблема вплоть до свежей версии крестов, где ввели лямбды, не имела адекватного решения. И то лямбды в данном случае костыль, т.к. по сути нам нужна ссылка на класс / на конструктор. Лямбда просто переводит проблему, не решаемую в объектной модели крестов, в плоскость, где она решаема.

geekless ★★
() автор топика

Объясни, пожалуйста, понятно и доходчиво, что же в приведенном фрагменте кода не так, кроме кучи строк сомнительной нужности.

netcat ★★
()
Ответ на: комментарий от netcat

См. как в gtkaction.c используется menu_item_type. Это в данном случае — правильный способ создать экземпляр неизвестного заранее класса.

А в приведенном коде захардкожено создание экземпляров конкретного класса.

geekless ★★
() автор топика
Ответ на: комментарий от geekless

как в крестах создать экземпляр «какого-то» класса.

Вам не нравится, что в статически типизируемом языке над типами нужно думать до компиляции кода?

O02eg ★★★★★
()
Ответ на: комментарий от geekless

В Qt можно через QMetaType::construct, или ты не об этом? Про чистые кресты не в курсе :}

Deleted
()
Ответ на: комментарий от geekless

Кстати, расскажи-ка мне, как в крестах создать экземпляр «какого-то» класса.

Это не недостаток, а правильно ограничение. Какой юзкейс у фабрики, которая может создавать «какие-то» объекты?

Используй полиморфизм, Luke!

KennyMinigun ★★★★★
()
Ответ на: комментарий от stevejobs

Матвей Кожев

Не тот ли это Матвей.. который Майя? :3

Ok
()
Ответ на: комментарий от KennyMinigun

Это не недостаток, а правильно ограничение. Какой юзкейс у фабрики, которая может создавать «какие-то» объекты?

Юзкейз в стартовом посте.

Используй полиморфизм, Luke!

И как мне его использовать, если конструктор типа выдаёт вполне конкретный тип?

geekless ★★
() автор топика
Ответ на: комментарий от O02eg

Вам не нравится, что в статически типизируемом языке над типами нужно думать до компиляции кода?

То есть ООП в крестах не работает. Ок.

geekless ★★
() автор топика
Последнее исправление: geekless (всего исправлений: 1)
Ответ на: комментарий от geekless

И как мне его использовать, если конструктор типа выдаёт вполне конкретный тип?

Так в том-то и дело, что фабрика производит объекты с определённым поведением.

Вот такой говнокод подходит: http://ideone.com/Y5jsQC

P.S. Прошу прощения за оверижиниринг :)

KennyMinigun ★★★★★
()
Ответ на: комментарий от KennyMinigun

говнокод

И в самом деле говнокод.

Так в том-то и дело, что фабрика производит объекты с определённым поведением.

Уф...

GtkAction должна иметь возможность производить «какой-то» GtkImageMenuItem, а какой конкретно это будет субкласс — ей насрать.

Неужели так сложно?

Правильный ответ в данном случае: virtual GtkImageMenuItem* create_menu_item() и переопределять этот метод в субклассе.

geekless ★★
() автор топика
Последнее исправление: geekless (всего исправлений: 1)
Ответ на: комментарий от geekless

GtkAction должна иметь возможность производить «какой-то» GtkImageMenuItem, а какой конкретно это будет субкласс — ей насрать.

я о том же.

KennyMinigun ★★★★★
()

Можешь еще для сравнения, написать что происходит в Qt, при тех же условиях?

nexfwall ★★★★
()
Ответ на: комментарий от stevejobs

GTK – это робот, сваренный из металлолома с ближайшей свалки. Причем, про пульт управления позабыли полностью, и управлять им можно, только замыкая оголенные проводки и дергая вручную нужные тросики. GTK – это набор принципов, найденных на свалке истории. Это нагромождение тысяч функций неизвестного назначения и происхождения. Это огромный и неповоротливый gobject, который писали пьяные марсиане.

Автор как будто в зеркало смотрел да свой портрет словесный писал

shimon ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.