Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Painting QPixmap in the center of QTableView cell

I have a QTableView that works very well, the first column holds some thumbnails, in each cell of this column the thumbnails are vertically centered, but not horizontally centered.

Do I really need to use a delegate? If yes, How to center them horizontally using QStyledItemDelegate?

like image 764
Mohamed Anwer Avatar asked Nov 16 '25 17:11

Mohamed Anwer


2 Answers

Construct your own delegate and inherit QStyledItemDelegate. Override the paint method.

Then do something like this:

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);

}
like image 96
kh25 Avatar answered Nov 18 '25 20:11

kh25


Drawing by yourself is not necessary, but a custom delegate - is. The styled item delegate uses the style's control element drawing code to draw a CE_ItemViewItem - see the source code for Qt 5.5.0. The drawing code takes the style option's decorationAlignment member into account. Unfortunately, there's no data role that would pass that alignment to the styles's implementation. Instead, you have to override the alignment in your delegate:

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);
  }
};

Then, to center the thumbnails:

view.setItemDelegateForColumn(0, 
  new DecorationAligningDelegate(Qt::AlignHCenter, &view));
//or
view->setItemDelegateForColumn(0, 
  new DecorationAligningDelegate(Qt::AlignHCenter, view));

If you really wished to paint it all yourself, even though it's unnecessary, the rectangle of the item to be painted is given in the style option (option.rect). To draw the pixmap centered in the item's rectangle, you could do as follows:

QStyleOption option;
QPixmap pix;
QPainter painter;
...
painter.save();
auto loc = option.rect.center() - pix.rect().center()
painter.drawPixmap(loc, pix);
painter.restore();
like image 25
Kuba hasn't forgotten Monica Avatar answered Nov 18 '25 21:11

Kuba hasn't forgotten Monica