Рисование элементов QTreeView с помощью QStyledItemDelegate - PullRequest
0 голосов
/ 17 сентября 2018

Я создал проект на основе Simple Tree Model Example из списка примеров Qt и отредактировал его модель, чтобы некоторые элементы также можно было проверить;Вот как это выглядит:

enter image description here

Я бы хотел, чтобы некоторые элементы были слегка смещены влево.Поэтому я создал делегат, получив производную QStyledItemDelegate и переопределив QStyledItemDelegate::paint следующим образом:

void TreeItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    if (index.column() == 0) {
        TreeItem *childItem = static_cast<TreeItem*>(index.internalPointer());
        if (childItem->type() == TreeItem::Type::Checkable) {
            QStyleOptionViewItem opt = option;
            QStyledItemDelegate::initStyleOption(&opt, index);

            const int desiredThreshold = 10;

            opt.rect.setX(opt.rect.x() - desiredThreshold);
            option.widget->style()->drawControl(QStyle::CE_ItemViewItem, &opt, painter, option.widget);

            return;
        }
    }

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

Таким образом, элементы типа TreeItem::Type::Checkable будут отрисовываться влево значением константы desiredThreshold(в данном случае 10 пикселей).

Пока все хорошо;все работает хорошо, и рисунок сделан правильно.Однако ...

Проблема в том, что, хотя элемент рисуется немного влево (что нормально), события мыши все еще работают так, как если бы элемент вообще не двигался;вот как это работает:

enter image description here

Можно ли сказать делегату, что весь элемент нарисован немного влево, чтобы при нажатии нафлажок (который также был перемещен вместе со всем элементом), модель будет корректно обновлена?

1 Ответ

0 голосов
/ 18 сентября 2018

Причина

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

Решение

Я бы предложил вам переопределить QStyledItemDelegate :: editorEvent ; чтобы отрегулировать положение QRect, возвращаемого QStyle :: subElementRect при вызове с QStyle :: SE_ItemViewItemCheckIndicator в качестве аргумента.

Пример

Рассмотрим следующие шаги:

  1. Добавить публичный editorEvent метод в ваш TreeItemDelegate класс
  2. Скопируйте реализацию по умолчанию из QStyledItemDelegate::editorEvent в ваш код
  3. Избегайте вызова частного метода QStyledItemDelegate, изменив

    const QWidget *widget = QStyledItemDelegatePrivate::widget(option);
    QStyle *style = widget ? widget->style() : QApplication::style();
    

    до

    QStyle *style = option.widget->style();
    
  4. Отрегулируйте положение checkRect, изменив

    QRect checkRect = style->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &viewOpt, widget);
    

    до

    QRect checkRect = style->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &viewOpt, option.widget).adjusted(-10, 0, -10, 0);
    
...