使用QStyledItemDelegate绘制QTreeView项目

时间:2018-09-17 17:33:17

标签: c++ qt qtreeview qstyleditemdelegate qstyle

我已经基于Qt示例列表中的Simple Tree Model Example创建了一个项目,并对其模型进行了编辑,以便还可以检查某些项目;看起来是这样的:

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 :(得分:3)

原因

您可以更改ItemViewItem在屏幕上的呈现方式,但不能更改其对用户操作的响应。

解决方案

我建议您重新实现QStyledItemDelegate::editorEvent;以调整QStyle::subElementRect作为参数调用时QStyle::SE_ItemViewItemCheckIndicator返回的QRect的位置。

示例

请考虑以下步骤:

  1. 在您的editorEvent类中添加公共TreeItemDelegate方法
  2. QStyledItemDelegate::editorEvent中的default implementation复制到您的代码中
  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);