QTreeView 绘制行的颜色

QTreeView color of painted row

我扩展了 QStyledItemDelegate 以在 QTreeView 的右侧绘制一些像素图。这很好用,但是,我意识到如果文本太长,像素图可能位于文本前面。

所以我在绘制像素图之前尝试绘制一个与背景颜色相同的矩形。

void MyItemDelegate::paint(
    QPainter *painter,
    const QStyleOptionViewItem &option,
    const QModelIndex &index) const
{
    ...
    QStyledItemDelegate::paint(painter, option, index);
    ...
    QStyleOptionViewItem opt = option;
    initStyleOption(&opt, index);
    ...
    painter->fillRect(rect, opt.backgroundBrush);
    painter->drawPixmap(topLeft, pixmap);
}

我知道除了opt.backgroundBrush之外所有变量都是正确的。无论有无 initStyleOption 调用,它始终是不可见的黑色。

然后我开始查看opt.stateopt.features的值,自己挑颜色。我在交替颜色 (QStyleOptionViewItem::Alternate) 方面取得了一些成功,但它开始变得冗长乏味,因为还有其他状态(悬停和选中)和其他 OS 可能有其他状态。一定有更简单的方法。

所以,我的问题是:当我在 paint 方法中时,如何获得将用于绘制行的实际颜色?或者,您有什么其他干净的方法可以避免这种情况吗?

我的处理方式可能不同。我不会先打电话:

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

第一。

然后,重要的部分:如果您知道项目上有多少个图标,您就可以计算边界矩形。

你怎么知道你有多少个图标?也许通过调用类似的东西:

bool hasIcon = index->data(YourAPP::HasIcons).toBool();

你的委托中可以有这样的东西:

void MyItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const {
...
QStyleOptionViewItem o = option;
initStyleOption(&o, index);
bool hasIcon = index->data(YourModel::HasIcons).toBool();
// or
bool hasCustomRole1 = index->data(YourModel::Role1).toBool();
bool hasCustomRole2 = index->data(YourModel::Role2).toBool();

if (hasIcon) {
    // width of your icons, can be like o.rect.height() * numbers of icons
    int width = 0;

    // shrink your first rectangle
    o.rect.adjust(0, 0, -width, 0);

    // create a second rectangle
    QStyleOptionViewItem o2 = option;
    initStyleOption(&o2, index);
    o2.rect.adjust(width, 0, 0, 0);

    // paint your icons
    ...
    painter->drawPixmap(o2, pixmap);
} else {
    QStyledItemDelegate::paint(painter, option, index);
}

如@G.M 所建议。我使用 QItemDelegate class 而不是 QStyledItemDelegate 并且我对绘图过程有更多的控制。特别是因为添加了 protected functions,例如 drawDisplay。覆盖此方法,我可以将 "display rectangle" 调整为比 Qt 计算的更小的大小。

void ActionsItemDelegate::drawDisplay(
    QPainter *painter,
    const QStyleOptionViewItem &option,
    const QRect &rect,
    const QString &text) const
{
    const int minX = ...; // x position of the left-most icon
    const int iconsWidth = rect.width() - (minX - rect.x());
    QItemDelegate::drawDisplay(painter, option, rect.adjusted(0, 0, -iconsWidth, 0), text);
}

缺点是UIchanges时使用QStyledItemDelegate。我不知道如何获得两者的好处:正常样式和更多控件。