使用Qt自定义代理实现正确的高亮显示

5
我正在制作一个表格控件,除了显示其模型中的DisplayRole之外,还要显示一些附加的文本数据。在所有其他方面,文本和单元格显示应该是相同的。我遇到困难的是正确显示高亮单元格。
我目前正在使用以下代码:
void MatchDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{

 if (option.state & QStyle::State_Selected)
      painter->fillRect(option.rect, option.palette.highlight());
 painter->save();
 QString str = qvariant_cast<QString>(index.data())+ "\n";
 str  += QString::number(qvariant_cast<float>(index.data(Qt::UserRole)));
 if (option.state & QStyle::State_Selected)
     painter->setBrush(option.palette.highlightedText());
 else
     painter->setBrush(qvariant_cast<QBrush>(index.data(Qt::ForegroundRole)));

 painter->drawText(option.rect, qvariant_cast<int>(index.data(Qt::TextAlignmentRole)), str);
 painter->restore();

}

然而,结果看起来像这样:

高亮单元格

文字颜色是错误的,单元格周围没有虚线,当控件失去焦点时,单元格仍然是蓝色的,而不像默认单元格一样变成浅灰色。应该如何改变绘图代码以解决这些问题?

看起来,您没有将QPen(笔的颜色和样式)设置为白色和Qt :: DashLine。 - Ashif
如何根据调色板设置笔? - Srv19
调用基类的绘制函数:"QStyledItemDelegate::paint(painter, option, index);" 可能会解决你的问题。 - Ashif
我希望重新实现那部分,而不仅仅是使用它。 - Srv19
默认情况下,当您选择一个项委托时,它将使用高亮文本和虚线边框突出显示您的背景。 - Ashif
我知道。但它只会将index.data()中的内容作为文本写入。我想改变显示的文本 - 但出于某些原因,我不想为此更改模型。如果我可以使用指定的文本调用基础委托,那就太好了。 - Srv19
1个回答

6
请尝试以下代码,它可以正常工作。
在选择时,请设置drawControl以便绘制虚线(让Qt在内部处理)。
选择单元格时解决了虚线、文本颜色和换行问题。
enter image description here
void MatchDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{         
QStyleOptionViewItemV4 opt = option;
        initStyleOption(&opt, index);

        const QWidget *widget = option.widget;
        QString str = qvariant_cast<QString>(index.data())+ "\n";
         str  += QString::number(qvariant_cast<float>(index.data(Qt::UserRole)));
           opt.text = "";
        //option
        QStyle *style = widget ? widget->style() : QApplication::style();


        if (option.state & QStyle::State_Selected)
        {
            // Whitee pen while selection
            painter->setPen(Qt::white);
            painter->setBrush(option.palette.highlightedText());
            // This call will take care to draw, dashed line while selecting
            style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget);
        }
        else
        {
            painter->setPen(QPen(option.palette.foreground(), 0));
            painter->setBrush(qvariant_cast<QBrush>(index.data(Qt::ForegroundRole)));
        }

        painter->drawText(option.rect, qvariant_cast<int>(index.data(Qt::TextAlignmentRole)), str);
    }

我已经尝试过了。 单元格正确地被突出显示,但由于某种原因,带有换行符的字符串未在两行上显示。 - Srv19
@Srv19 已更新以支持多行,很可能会得到解决。 - Ashif
1
2022年更新此代码片段以适用于Qt6。可以将行if (option.state & QStyle::State_Selected)更改为int highlightedFlags = QStyle::State_Enabled | QStyle::State_Selected | QStyle::State_Active; if ((option.state & highlightedFlags) == highlightedFlags)以更好地反映应用程序焦点的丢失和多个单元格选择。QPalette::foreground()已被弃用并移除,使用QPalette::windowText()代替。在绘制文本时,我修改了矩形,如option.rect.adjusted(3, 3, -3, -3)以匹配其他单元格绘制(有些hacky但不确定还有其他方法)。 - Salami

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接