在QTableView单元的中心绘制QPixmap

在QTableView单元的中心绘制QPixmap,qt,qtableview,qstyleditemdelegate,Qt,Qtableview,Qstyleditemdelegate,我有一个工作非常好的QTableView,第一列包含一些缩略图,在该列的每个单元格中,缩略图垂直居中,但不是水平居中 我真的需要使用代理吗? 如果是,如何使用QSTYLEDITMDELEGATE将它们水平居中?不需要自己绘制,但需要自定义委托。样式化项委托使用样式的控制元素绘图代码绘制CE\u ItemViewItem-请参阅。图形代码考虑样式选项的decorationAlignment成员。不幸的是,没有数据角色可以将这种对齐传递给样式的实现。相反,您必须替代代理中的对齐方式: class D

我有一个工作非常好的QTableView,第一列包含一些缩略图,在该列的每个单元格中,缩略图垂直居中,但不是水平居中

我真的需要使用代理吗?
如果是,如何使用QSTYLEDITMDELEGATE将它们水平居中?

不需要自己绘制,但需要自定义委托。样式化项委托使用样式的控制元素绘图代码绘制
CE\u ItemViewItem
-请参阅。图形代码考虑样式选项的
decorationAlignment
成员。不幸的是,没有数据角色可以将这种对齐传递给样式的实现。相反,您必须替代代理中的对齐方式:

class DecorationAligningDelegate : public QStyledItemDelegate {
  Q_OBJECT
  Qt::Alignment const m_alignment;
public:
  explicit DecorationAligningDelegate(Qt::Alignment alignment, QObject * parent = 0) :
    QStyledItemDelegate(parent), m_alignment(alignment) {}
  Qt::Alignment alignment() const { return m_alignment; }
  void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const {
    auto opt = option;
    opt.decorationAlignment = m_alignment;
    QStyledItemDelegate::paint(painter, opt, index);
  }
};
然后,要使缩略图居中,请执行以下操作:

view.setItemDelegateForColumn(0, 
  new DecorationAligningDelegate(Qt::AlignHCenter, &view));
//or
view->setItemDelegateForColumn(0, 
  new DecorationAligningDelegate(Qt::AlignHCenter, view));
如果您确实希望自己绘制所有内容,即使不需要,要绘制的项目的矩形也会在样式选项(
option.rect
)中给出。要以项目矩形为中心绘制像素贴图,可以执行以下操作:

QStyleOption option;
QPixmap pix;
QPainter painter;
...
painter.save();
auto loc = option.rect.center() - pix.rect().center()
painter.drawPixmap(loc, pix);
painter.restore();

构造自己的委托并继承QStyledItemDelegate。重写绘制方法

然后像这样做:

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

     QPixmap pixmap;
     pixmap.load("Your pixmap file path");
     pixmap = pixmap.scaled(option.rect.width(), option.rect.height(), Qt::KeepAspectRatio);

    // Position our pixmap
    const int x = option.rect.center().x() - pixmap.rect().width() / 2;
    const int y = option.rect.center().y() - pixmap.rect().height() / 2;

    if (option.state & QStyle::State_Selected) {
        painter->fillRect(option.rect, option.palette.highlight());         
    }

    painter->drawPixmap(QRect(x, y, pixmap.rect().width(), pixmap.rect().height()), pixmap);

}
auto *item = new QTableWidgetItem();
item->setIcon(QIcon("Your pixmap file path"));

我将只留下我的版本,文学是两个答案的结合

class DecorationAligningDelegate : public QStyledItemDelegate
{
    Q_OBJECT

public:
    explicit DecorationAligningDelegate(Qt::Alignment alignment, QObject *parent = nullptr)
    : QStyledItemDelegate(parent), m_alignment(alignment) {}

    Qt::Alignment alignment() const { return m_alignment; }

    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        QIcon icon = QIcon(qvariant_cast<QIcon>(index.data(Qt::DecorationRole)));

        if (option.state & QStyle::State_Selected)
        {
             painter->fillRect(option.rect, option.palette.highlight());
        }

        icon.paint(painter, option.rect, m_alignment);
    }

private:
    Q_DISABLE_COPY(VDecorationAligningDelegate)
    Qt::Alignment const m_alignment;
};

别忘了设置委托。

那么,我必须使用委托吗?@MohamedAnwer是的,你可以,但是委托很琐碎,不能自己绘制任何东西。我已经展示了完成这种对齐的委托的完整来源,以及如何在所需列上设置它。对于Qt的视图和样式代码中的遗漏,这是一个简单的解决方法。我完全完成了第一个代码段,垂直对齐已经消失,但仍然没有水平对齐,我将Qt::AlignHCenter更改为(Qt::AlignHCenter | Qt::AlignVCenter),垂直对齐再次显示,但仍然没有水平对齐,你现在怎么想?@MohamedAnwer要么
QIcon::paint
被破坏,忽略了垂直对齐,要么视图“聪明”,只提供了足够的垂直区域来适应图标,这样对齐就变成了不可操作的。Add
qDebug()我使用的是Qt 5.5,矩形比pixmap大,顺便说一句,当我调整小部件宽度时,矩形宽度会扩大