2

我已经基于Simple Tree Model Example来自 Qt 示例列表的项目创建了一个项目并编辑了它的模型,以便也可以检查一些项目;这是它的样子:

在此处输入图像描述

我希望将一些项目稍微向左移动。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 像素)绘制到左侧。

到现在为止还挺好; 一切正常,绘图正确完成。然而...

问题是虽然项目稍微向左绘制(这没关系),但鼠标事件仍在工作,就好像项目根本没有移动一样;这是它的工作原理:

在此处输入图像描述

是否可以告诉代表整个项目略微向左绘制,以便当我单击复选框(也与整个项目一起移动)时,模型会正确更新?

4

1 回答 1

4

原因

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

解决方案

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

例子

考虑以下步骤:

  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);
    
于 2018-09-18T03:55:35.590 回答