Когда определять класс GTK, когда использовать сигналы? - PullRequest
9 голосов
/ 06 января 2012

Я довольно новичок в GTK, и я возился с моим первым "серьезным" приложением GTK (gtk + -3).Я хотел бы использовать мудрость чужого опыта о том, когда уместно определить новый класс GTK или просто использовать «ванильные» классы GTK и реализовать поведение с помощью обработчиков сигналов.

Я имеюДо сих пор сталкивался с двумя примерами:

Пользовательские виджеты

Я создаю новый виджет: в основном GtkDrawingArea, который я использую для отображения некоторых данных.Первоначально я предполагал, что лучший способ реализовать это - создать подкласс GtkDrawingArea, используя G_DEFINE_TYPE, и предоставить свой собственный обратный вызов отрисовки:

static void mywidget_class_init(MyWidgetClass *klass)
{
    GTK_WIDGET_CLASS(klass)->draw = mywidget_draw;
}

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

[Мой пользовательский виджет в конечном итоге предоставит больше, чем просто обратный вызов отрисовки, поскольку он должен быть интерактивным, ноэто произойдет позже ...]

Приложение Windows

Мое приложение состоит из нескольких различных окон, которые в настоящее время являются ванильными GtkWindows:

struct myapp_somewindow {
    struct myapp *app;
    GtkWindow    *window;
    GtkWidget    *some_label_that_is_updated;
    /*... other window-specific fields */
}

Когда структура myapp_somewindow имеет структуруПри инициализации я создаю GtkWindow с gtk_window_new(), инициализирую виджеты / макеты / и т. д. и подключаю сигналы.[Вероятно, в конечном итоге я буду использовать файлы .ui для более сложных случаев, но окна пока достаточно просты.]

Это можно сделать, определив новый подкласс GtkWindow, но я неОпределенно, когда накладные расходы на код при определении нового класса становятся целесообразными.


Я знаю, что, вероятно, нет строгих правил для какого подхода, но есть какие-то общие рекомендации, которые следует использовать при создании этих проектоврешения?Есть ли серьезные подводные камни в любом подходе?

Ответы [ 2 ]

7 голосов
/ 18 февраля 2012

Я работал над небольшим количеством проектов, использующих GTK + и Clutter, и я всегда продвигал интенсивное использование подклассов общих виджетов / актеров к более конкретным.

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

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

Хорошим примером проекта, в котором использовалась эта стратегия создания подклассов, являются задачи и, в частности, внутренняя вспомогательная библиотека: http://git.gnome.org/browse/tasks/tree/libkoto Это означало, что когда мы хотели перенести приложение на новую платформу или предоставить с другой точки зрения на данные было довольно легко просто склеить существующие виджеты и древовидные модели по-другому.

Если вы хотите использовать C и считаете подклассы немного утомительными, вы можете попробовать этот инструмент: http://git.gnome.org/browse/turbine/, чтобы помочь автоматизировать создание ваших подклассов.

1 голос
/ 06 января 2012

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

Это предполагает, что для вашего второго варианта использования, окна приложения, вы всегда должны определять новый класс.

Одной из причин сделать это таким образом является то, что ваш виджет может начинаться с простого, с поведением, которое вы можете реализовать исключительно с помощью обработчиков сигналов, но позже оно может стать более сложным. Например, предположим, что вы хотите добавить резервное хранилище в область рисования. «Воспринимаемая стоимость» реорганизации вашего простого виджета в класс высока, тогда как он сделает ваш код намного чище, чем обходить его.

Еще одним преимуществом является то, что классы могут иметь свойства. Вы можете связать эти свойства со свойствами других классов или с ключами GSettings, что является действительно мощным механизмом и может сделать ваш код действительно простым.

Если вам не нравятся все образцы классов, подумайте о программировании на Vala.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...