Centering DecorationRole icon in QTableView cell
Unsolved
General and Desktop
-
I've subclassed QStyledItemDelegate and overrode the paint function. Then, I set the delegate appropriately. Here is the paint override code below:
{ QStyleOptionViewItem opt = option; opt.decorationAlignment = Qt::AlignHCenter; QStyledItemDelegate::paint(painter, opt, index); }
Even so, the icon does not center. However, if I set:
opt.decorationPosition = QStyleOptionViewItem::Top;
...then the icon does center horizontally. However, it is pushed up to the "top" which is not what I want. How can I center my icon horizontally and vertically?
-
Hi,
What if you use
Qt::AlignCenter
? -
Can you provide a minimal compilable sample that shows this ?
-
@SGaist Sure, here it is:
class Model : public QAbstractTableModel { int rows; int columns; QIcon flagIcon; public: explicit Model(QObject * parent = nullptr) : QAbstractTableModel(parent) { rows = 3; columns = 3; flagIcon.addFile(QCoreApplication::applicationDirPath() + "/flag.png"); } int rowCount(const QModelIndex &parent = QModelIndex()) const { return rows; } int columnCount(const QModelIndex &parent = QModelIndex()) const { return columns; } QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const { if (role == Qt::DecorationRole) return flagIcon; else return QVariant(); } }; class FlagDelegate : public QStyledItemDelegate { public: FlagDelegate(QObject * parent) : QStyledItemDelegate(parent) { } void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QStyleOptionViewItem opt = option; opt.decorationAlignment = Qt::AlignCenter; QStyledItemDelegate::paint(painter, opt, index); } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); QTableView table; table.setFixedWidth(400); table.setFixedHeight(400); Model model(&table); table.setModel(&model); FlagDelegate delegate(&table); table.setItemDelegate(&delegate); table.show(); return a.exec(); }
Again, in the overridden paint method, the icon only centers if I set opt.decorationPosition to Top or Bottom.
-
The solution is to manually draw the pixmap of the icon with the painter object, like so:
void FlagDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QRect rect = option.rect; QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole)); QPixmap pix = icon.pixmap( rect.size() *= 0.70 ); QPoint p = QPoint((rect.width() - pix.width())/2, (rect.height() - pix.height())/2); painter->drawPixmap(rect.topLeft() + p, pix); }
-
void FlagDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { const QStyle* style = option.widget ? option.widget->style() : qApp->style(); style->drawPixmap(option.rect,Qt::AlignCenter,index.data(Qt::DecorationRole).value<QIcon>().pixmap(option.rect.size())); }