Russian Qt Forum
Ноябрь 01, 2024, 16:39 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Помогите с иерархией классов.  (Прочитано 5143 раз)
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« : Июль 12, 2012, 17:02 »

Добрый день.
У меня в проекте все объекты на сцене наследуются от QGraphicsObject.
Для добавления функционала сериализации и связки с логикой программы путем множественного наследования добавил в качестве предков еще несколько классов.
CXMLSerialisation - класс отвечающий за сохранение и загрузку данных объекта в XML поток.
CObjectViewLink - класс, отвечающий за связку графического представления на сцене с логикой.
QCommonRailItem - расширение QGraphicsItem (добавление мигания, id, имя и т.п., чего не хватает базовым классам).
и того есть базовый класс для всех объектов на сцене QRailItem.

Код:
class  QAbstractRailItem: public QCommonRailItem
{
...
}

class QRailItem : public QAbstractRailItem, public  CObjectViewLink, public CXMLSerialisationObject
{
...
}

от этого QRailItem уже у меня наследуется куча классов с довольно сложной структутрой и механизмами отрисовки (векторная алгебра и т.п.)
Все работает отлично. Но столкунлся с тем, что на сцену нужно выводить виджет QListWidget.
Проблема в том, что все контейнеры у меня оперируют QRailItem. а виджет впихнуть на сцену получается только можно через QGraphicsProxyWidget - предок у которого QGraphicsWidget.
Т.е. получается нужно заводить еще и контейнеры для классов на основе QGraphicsProxyWidget+QCommonRailItem+CObjectViewLink+CXMLSerialisationObject+(еще классы для возможности изменения размеров и положения виджета на сцене, т.к. сами Qt почему то такой функционал не предоставили).
Может есть какой то более элегантный способ сделать нормальную иерархию классов для проекта?
Понимаю что описано все скудно и сухо, но изза комерческой тайны не могу все раскрыть Грустный
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #1 : Июль 12, 2012, 17:10 »

К одному логическому объекту может быть привязано много графических посредством т.н. ролей.
Например к лог.объекту "Генератор" может быть привязно несколько меток и несколько кнопок на сцене, доступ к каждой можно получить по ее роли. роль - строка в опред. формате.
Т.е. каждый лог. объект содержит в себе хеш вида <QString,QGraphicsObject*>.
В свою очередь графический элемент может быть привязан только к одному логическому элементу (разного типа опять же на основании роли).
Для хранение и оперирования логическими и графическими объектами ввел т.н. провайдеры, которые могут создавать,удалять,менять свойства объектов.
Все они оперируют QRailItem* (провайдеры граф. элеметов).
Теперь нужно добавить провайдеры, которые будут оперировать виджетами. Раньше у меня было два вида провайдеров, но хочется что бы предок был общий, а все перенести на виртуальные методы. Боюсь что описал проблему не совсем понятно. По возможности сформулирую более понятно.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Июль 12, 2012, 18:16 »

Возможно и необязательно укладывать QGraphicsProxyWidget в общую схему. Из простых решений можно не наследоваться от QGraphicsObject а сделать указатель на него членом (не знаю какого класса у Вас - всю иерархию Вы не предъявили)
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #3 : Июль 16, 2012, 15:30 »

Суть такова, что нужно что бы в общем контейнере можно было хранить как объекты наследованные от QGraphicsObject так и объекты наследованные от QGraphicsProxyWidget (так как есть необходимость отображать стандартные виджеты на сцене, например таблицы, списки). Логично, что общий предок у них QGraphicsItem. Но для удобства мне еще нужно оперировать полями из дополнительных моих классов (такие как id, name, font, className) и методами/слотами (load,save,blink,...).
Записан
_OLEGator_
Гость
« Ответ #4 : Июль 17, 2012, 08:49 »

Чтобы сделать такой гибкий механизм - придется уходить от наследования, создавать абстрактные базовые классы и не наследоваться от них, а держать экземплярами, вызывая необходимые методы. Описана только часть задачи, постарайтесь описать хотя бы в глубину, зачем идет наследование от QGraphicsObject например, для переопределения каких то методов или что?
Если требуется например загрузка или сохранение объекта, я бы сделал один менеджер на все объекты, который допустим выдирал все property и сохранял их по типу объекта - так максимально гибко и расширяемо, слабую связанность между классами надо создавать, а наследования - это плохо расширяемо при разнородных объектах...
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #5 : Июль 17, 2012, 11:12 »

Суть такова: есть простые объекты (светофор, стрелка, которые состоят из простых граф. примитивов - эллипсов, линий, замкнутых полигонов). Их можно располагать на сцене как угодно (согласну плану). Так же на этой сцене нужно расположить несколько виджетов (в основном QListWidget), что бы отображать в них разные сообщения. Наследование от QGraphicsObject необходимо, так как нужно отлавливать события перемещения объектов на сцене в режиме редактирования (для инспектора объектов и композиции), + генерятся свои сигналы, используются слоты в этих объектах (например задать цвет текста, шрифт и т.п.). Эти объекты хранятся в контейнерах. Могут удаляться, добавляться, изменяться, сохраняться и загружаться (в XML).
Хочется что бы контейнеры могли содержать как объекты наследованные от QGraphicsObject так и наследованные от QGraphicsProxyWidget. Не хочется писать свой виджет списка (долго и зачем).
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #6 : Июль 17, 2012, 11:14 »

+что бы был доступ к челнам классов QCommonRailItem, CObjectViewLink и т.п.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Июль 17, 2012, 14:00 »

Чтобы сдвинуть обсуждение с мертвой точки предлагаю нарисовать диаграмму классов (как угодно, красивости не нужны). Просто имена классов и линии наследования, начиная от базовых классов и до контейнера
Записан
_OLEGator_
Гость
« Ответ #8 : Июль 17, 2012, 14:38 »

Сумбурное объяснение, без диаграммы классов и краткого описания их функции не понятно.
Меня не интересуют конкретные детали (светофоры, кошки, собаки) - меня интересуют абстрактные функции базовых классов и причины наследования от классов Qt.
Записан
Akon
Гость
« Ответ #9 : Июль 18, 2012, 08:02 »

Суть такова, что нужно что бы в общем контейнере можно было хранить как объекты наследованные от QGraphicsObject так и объекты наследованные от QGraphicsProxyWidget (так как есть необходимость отображать стандартные виджеты на сцене, например таблицы, списки). Логично, что общий предок у них QGraphicsItem. Но для удобства мне еще нужно оперировать полями из дополнительных моих классов (такие как id, name, font, className) и методами/слотами (load,save,blink,...).
Ну, в контейнере хранится общий предок, далее dynamic_cast/qobject_cast для проверки конкретного типа и доступ к расширяющему интерфейсу этого типа. Для удобства пользования контейнером можно сделать фильтрующие по типу итераторы (есть boost::filter_iterator), или, можно сделать в соответствии с типом дополнительные контейнеры (ленивые или вычисляемые на лету - зависит от специфики задачи).
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.285 секунд. Запросов: 23.