Правильная реализация QStyledItemDelegate

У меня есть класс (EditorTagManager), который содержит QTreeWidget. Во время выполнения дерево может содержать любое количество элементов тегов, каждый из которых можно проверить. Я пытаюсь добавить горизонтальные линии между QTreeWidgetItems, чтобы было ясно, что эти теги не связаны и должны быть отделены друг от друга (каждый элемент является корневым узлом).

Из моих исследований по этому вопросу я понял, что единственный способ управлять внешним видом QtreeWidgetItems в какой-либо значимой степени — это подкласс QStyledItemDelegate и привязка делегата к QTreeWidget. Это своего рода абстрактное понятие, поэтому я не совсем понимаю его. Поскольку мне никогда раньше не приходилось создавать подклассы для объектов Qt, я не уверен, что делаю это правильно.

Поскольку документация Qt на самом деле не объясняет, как это сделать, я использовал файлы settingsdialog.cpp/.h из исходного кода Clementine 1.0.1 в качестве моего руководства/справочника, потому что окно настроек Clementine использует аналогичные разделители в своем QTreeWidget. Я пытаюсь реконструировать свое собственное решение из кода Клементины, единственная проблема заключается в том, что реализация Клементины делает то, что мне не нужно (поэтому мне нужно выяснить, что относится к моему коду, а что нет). Вот что привело меня к этому моменту; мой код очень похож на код Clementine (я просто изменил имя класса делегата):

Вот мое текущее объявление заголовка делегата в editortreemanager.h:

class TagListDelegate : public QWidget
{

public:
    TagListDelegate(QObject* parent);
    void paint(QPainter* painter, const QStyleOptionViewItem& option,
                const QModelIndex& index) const;
};

Вот мой текущий источник делегата в editortreemanager.cpp:

TagListDelegate::TagListDelegate(QObject *parent) :
    TagListDelegate(parent){

}

void TagListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                            const QModelIndex &index) const{

}

Несмотря на то, что TagListDelegate::paint() на самом деле еще ничего не делает, я просто хочу, чтобы этот код работал правильно, прежде чем пытаться изменить внешний вид QTreeWidgetItems. Моя цель — сделать это максимально простым на данный момент.

Все скомпилировалось нормально, пока я не сказал QTreeWidget (ui->AvailableTags) использовать делегат:

ui->AvailableTags->setItemDelegate(new TagListDelegate(this)); 

Ошибка компилятора гласит:

/home/will/qt_projects/robojournal/ui/editortagmanager.cpp:211: ошибка: нет соответствующей функции для вызова 'QTreeWidget::setItemDelegate(TagListDelegate*)'

Я немного запутался здесь, поэтому я определенно был бы признателен за помощь в выяснении этого.

ОБНОВЛЕНИЕ (30.07.13):

Мой класс Delegate теперь выглядит так:

Источник:

TagListDelegate::TagListDelegate(QStyledItemDelegate *parent) :
    TagListDelegate(parent){

}

void TagListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                            const QModelIndex &index) const{

    QStyledItemDelegate::paint(painter, option, index);

}

Объявление заголовка:

class TagListDelegate : public QStyledItemDelegate
{

public:
    TagListDelegate(QStyledItemDelegate* parent);
    void paint(QPainter* painter, const QStyleOptionViewItem& option,
                const QModelIndex& index) const;
};

ОБНОВЛЕНИЕ (31.07.13)

Вот как сейчас выглядят мои занятия:

заголовок:

class TagListDelegate : public QStyledItemDelegate
{

public:
    TagListDelegate(QObject* parent);
    QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
    void paint(QPainter* painter, const QStyleOptionViewItem& option,
                const QModelIndex& index) const;
};

источник:

TagListDelegate::TagListDelegate(QObject *parent)
    : TagListDelegate(parent){

}

QSize TagListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
     QSize ret = QStyledItemDelegate::sizeHint(option, index);
     return ret;
}


void TagListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                            const QModelIndex &index) const{

    QStyledItemDelegate::paint(painter, option, index);

}

person Will Kraft    schedule 29.07.2013    source источник


Ответы (1)


Вы не создаете подкласс QStyledItemDelegate в своем коде. Вы создаете подкласс QWidget. Изменять

class TagListDelegate : public QWidget

to:

class TagListDelegate : public QStyledItemDelegate

И не забудьте включить заголовок:

#include <QStyledItemDelegate>
person thuga    schedule 30.07.2013
comment
Хорошо, я сделал это, но вызвал делегата, запустив ui-›AvailableTags-›setItemDelegate(new TagListDelegate(this)); все еще не работает. - person Will Kraft; 30.07.2013
comment
@WillKraft В своем конструкторе вы запрашиваете объект типа QStyledItemDelegate в качестве родителя, когда вы должны запрашивать тип QWidget или QObject. - person thuga; 31.07.2013
comment
Thuga: Ваш последний совет немного помог; код компилируется теперь, когда я вызываю делегата, но приложение segfaults всякий раз, когда создается экземпляр делегата. Отладчик говорит, что он как-то связан с конструктором, а именно с тем, что родитель (this) недоступен. Мой последний код (см. выше) в основном представляет собой урезанную версию кода делегата от Clementine, поэтому я не уверен, в чем проблема. - person Will Kraft; 01.08.2013
comment
На самом деле, я, возможно, только что исправил это. Теперь он не падает, когда я установил конструктор в TagListDelegate::TagListDelegate(QObject *parent) : QStyledItemDelegate(parent){ } - person Will Kraft; 01.08.2013
comment
Да, теперь это определенно исправлено. Спасибо за помощь. - person Will Kraft; 01.08.2013
comment
@WillKraft О да, вы действительно хотите вызвать конструктор суперкласса в списке инициализации конструктора вашего подкласса, а не конструктор того же класса. Извините, я пропустил это. Я рад, что вам удалось решить эту проблему. - person thuga; 01.08.2013