2

我的 QList 小部件有一个 QStyledItemDelegate:

class MappingDisplayWidgetDelegate: public QStyledItemDelegate
{
    Q_OBJECT
public:
    MappingDisplayWidgetDelegate(QObject *parent=NULL);
    virtual void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const;
    virtual QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const;
};

它的绘画方法看起来像:

void MappingDisplayWidgetDelegate::paint ( QPainter * painter,
                                           const QStyleOptionViewItem & option,
                                           const QModelIndex & index ) const
{
    if (option.state & QStyle::State_Selected)
        painter->fillRect(option.rect, option.palette.highlight());
    else if (option.state & QStyle::State_MouseOver)
        painter->fillRect(option.rect, option.palette.midlight());


    QFontMetrics fm(option.font);

    QString filename = index.data(Qt::DisplayRole).toString();

    QRect outline = option.rect;
    int outmid = outline.center().y();

    QRect fnBound = fm.boundingRect(filename);
    int fnBoundMid = fnBound.center().y();
    fnBound.moveLeft(outline.left());
    fnBound.translate(0, outmid - fnBoundMid);

    painter->drawText(fnBound, Qt::AlignVCenter | Qt::AlignLeft, filename);

}

现在这可行,但是对 State_Selected 和 State_MouseOver 的处理不会产生与默认列表相同的结果。这是左侧上面代码的屏幕截图(我在 Win7 系统上运行),右侧是标准 QListWidget。你可以看到 QListWidget 有很好的渐变,而我的项目只有简单的颜色。

在此处输入图像描述

我想绘制我的项目以正确匹配标准小部件,但我不太清楚如何。我没有在选项中看到任何可以为我提供所需信息的内容。

编辑添加:请注意,这是一个有点玩具的例子。真正的代码除了一个字符串之外还有很多其他的东西,并且有一个适当的(和工作的)sizeHint 函数。这只是一个演示问题的玩具。

4

3 回答 3

2

在用于绘制该元素的源代码中,进行了以下调用:

// draw the background
proxy()->drawPrimitive(PE_PanelItemViewItem, opt, p, widget);

我怀疑您可能想做类似于以下的事情:

style().drawPrimitive(QStyle::PE_PanelItemViewItem, option, painter, NULL);

您可能必须使用option参数来获得正确的矩形目标。不幸的是,我现在使用的计算机没有设置来测试任何这些,所以 YMMV。

于 2012-09-24T16:58:36.867 回答
1

我有同样的问题——我想要一个完全自定义的绘画功能,但要利用内置的漂亮选择绘画。我已经尝试了下面的代码,到目前为止,我发现它运行良好,没有负面影响:

void MassIndexItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex& index) const {
    QStyledItemDelegate::paint(painter, option, QModelIndex());
    //Above, note that rather than passing >index< to the inherited function, I pass a default, invalid index.
    //Since my model's data() function returns an empty QVariant for invalid indexes,
    //I get the default selection painting, but no other data is painted in any way.

    //Below, I can do whatever painting I want and it will show up on top of the pretty selection paint
    painter->drawEllipse(option.rect);
}
于 2016-02-26T00:35:27.753 回答
0

我将其详细说明为一个可用的解决方案,尽管它不是一个很好的解决方案。

如果我没有在项目的 DisplayRole 中放置任何内容,那么我可以调用底层的 QStyledItemDelegate::paint 例程,它只会绘制正确的背景,因此:

void MappingDisplayWidgetDelegate::paint ( QPainter * painter,
                                           const QStyleOptionViewItem & option,
                                           const QModelIndex & index ) const
{
    QStyledItemDelegate::paint(painter, option, index);

    QFontMetrics fm(option.font);

    QString filename = index.data(Qt::UserRole).toString();

    QRect outline = option.rect;
    int outmid = outline.center().y();

    QRect fnBound = fm.boundingRect(filename);
    int fnBoundMid = fnBound.center().y();
    fnBound.moveLeft(outline.left());
    fnBound.translate(0, outmid - fnBoundMid);

    painter->drawText(fnBound, Qt::AlignVCenter | Qt::AlignLeft,
                      filename);
}

我不喜欢这样,我将暂时尝试 Dave 的建议,但如果遇到困难,这似乎确实有效。不利的一面是它意味着你不能使用 DisplayRole,所以你不能在 QListWidget 中使用 findItems。

于 2012-09-24T17:20:51.870 回答