Есть иерархическая структура данных. Данные хранят в себе переменные разных типов (как стандартные Qt-ые типы, так и кастомные).
С моделью для такой структуры проблем нет. А представление должно быть по типу инспектора объектов в Qt дизайнере. Сложность заключается в том, что нужно в зависимости от типа переменных отображать значения этих переменных (возможно даже кнопки и т.д. вместе с текстом или без) и редактировать их. Во всех книжках и примерах используют делегаты только для определенных столбцов или строк модели. Для столбцов с разными данными можно выкрутиться конструкциями типа if else с проверкой типа у QVariant, что не есть гуд. Нужно, чтобы делегат автоматически отрисовывал значение типа и возвращал нужный редактор. Также нужно, что бы элементы, имеющие потомков, отображались и реагировали на действия пользователя отлично от элементов без потомков.
Нашел QtPropertyBrowser (с помощью него сделан инспектор объектов в Qt дизайнере), но он отображает только стандартные Qt-ые типы, в исходниках какой-то ад, а также по нему нет документации и вообще походу забит болт еще со времен Qt4, ибо версию с гитхаба Qt я скомпилить так и не смог, а получилось скомпилить только версию для Qt4, которую кто-то давным давно портировал под Qt5. Есть еще либа
QtnProperty, но на нее нет документации, только статья на хабре и парочка инструкций на гитхабе. Сборка этой либы у меня получается только статическая, что мне не подходит. Да и мне кажется можно сделать все проще и легче, чем там.
Есть мысля сделать делегат с фабрикой редакторов и рисовальщиков для различных типов данных(Что-то типа как в QtnProperty). Для каждого типа данных в фабрике регистрируем редактор и рисовальщик(либо делегата, который будет иметь методы создания редактора и отрисовки, в общем способы есть разные).
Примерный код, показывающий идею, представлен ниже.
Получить имя типа можно из индекса разными способами. Либо через QVariant, но тогда придется регать кастомный тип в QVariant. Либо хранить имя типа в данных, и из индекса получать указатель на данные.
Имеет ли смысл так делать и есть ли другие варианты?
C++ (Qt)
class TypePainter;
class DelegateFactory;
class CustomDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
CustomDelegate (QWidget *parent = 0) : QStyledItemDelegate(parent) {}
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QString name = typeNameForIndex(index);
TypePainter * painter = delegateFactory->createPainter(name);
painter >paint(painter, option, index);
}
QWidget * createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QString name = typeNameForIndex(index);
QWidget * editor = delegateFactory->createEditor(name);
return editor;
}
//...
private:
DelegateFactory * m_delegateFactory;
};
class DelegateFactory
{
public:
DelegateFactory ();
QWidget * createEditor(const QString & typeName);
TypePainter * createPainter(const QString & typeName);
//...
private:
QMap<QString, QWidget *> m_editors;
QMap<QString, TypePainter *> m_painters;
};
class TypePainter
{
public:
TypePainter ();
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) = 0;
};