我的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函数。这只是一个展示问题的玩具。
答案 0 :(得分:1)
在用于绘制该元素的source code中,进行以下调用:
// draw the background
proxy()->drawPrimitive(PE_PanelItemViewItem, opt, p, widget);
我怀疑你可能想做类似以下的事情:
style().drawPrimitive(QStyle::PE_PanelItemViewItem, option, painter, NULL);
您可能需要使用option
参数来获取正确的矩形目标。不幸的是,我现在使用的计算机并没有设置为测试任何这些,所以YMMV。
答案 1 :(得分: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);
}
答案 2 :(得分: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);
}
我不喜欢这样,我会暂时尝试戴夫的建议,但如果一个人卡住,这似乎确实有效。在不利方面,这意味着您无法使用DisplayRole,因此您无法在QListWidget中使用findItems。