How can I center QCheckBox in QTableView?
-
@raven-worx, wait! I confused you and me. This '1' is my custom printout. So what you suggested printing just gives following output:
QFlags<Qt::AlignmentFlag>()
-
@CuriousPan
Qt::AlignLeft 0x0001 Aligns with the left edge.
So this value
1
is left alignment, just as per your picture, and no kind of centering specified, which would have value4
. -
@CuriousPan said in How can I center QCheckBox in QTableView?:
@JonB, it always retruns QFlagsQt::AlignmentFlag() 1 which is Qt::DecorationRole, right?
That's what you wrote. See that
1
? Can you please concentrate on one thing at a time. -
@CuriousPan
So that would be the value for left-align. Either you are not setting or returning the desired "center" flag on your item for theQt::TextAlignmentRole
--- you have to do that if you want it centered, that's what the code does --- or you are not looking at the right item/index. -
- Print out
index.column()
in the delegate. - Print out
RecurrentColumn
. - Put a
qDebug()
just abovereturn Qt::AlignCenter
in your "screenshot" to make sure it's being hit. - Please don't paste code as screenshots, paste it as code. Show where you have that code and what is above the extract you show.
- Print out
-
index.column()
in the delegate has the proper number.4
in my case as long as it is 4th (starting from 0) column in the table view.- What do you mean by printing
RecurrentColumn
?
//checking other roles } else if (index.isValid() && role == Qt::TextAlignmentRole) { switch (index.column()) { case RecurrentColumn: qDebug() << "Hit"; return Qt::AlignCenter; case TotalColumn: return {Qt::AlignRight | Qt::AlignVCenter}; case PlnTotalColumn: return {Qt::AlignRight | Qt::AlignVCenter}; return Qt::AlignCenter; } } // "Hit" is getting printed.
- Okay, will try to value your time and effort :)
-
@CuriousPan I have fixed the issue.
I used pretty dirty, but working trick: setQt::AlignedCenter
right in the delegate:void CenteredCheckBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QStyleOptionViewItem opt = option; const QWidget *widget = option.widget; initStyleOption(&opt, index); QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, widget); if (opt.features & QStyleOptionViewItem::HasCheckIndicator) { switch (opt.checkState) { case Qt::Unchecked: opt.state |= QStyle::State_Off; break; case Qt::PartiallyChecked: opt.state |= QStyle::State_NoChange; break; case Qt::Checked: opt.state |= QStyle::State_On; break; } auto rect = style->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &opt, widget); opt.rect = QStyle::alignedRect(opt.direction, Qt::AlignCenter/*index.data(Qt::TextAlignmentRole).value<Qt::Alignment>()*/, rect.size(), opt.rect); opt.state = opt.state & ~QStyle::State_HasFocus; style->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &opt, painter, widget); } else if (!opt.icon.isNull()) { // draw the icon QRect iconRect = style->subElementRect(QStyle::SE_ItemViewItemDecoration, &opt, widget); iconRect = QStyle::alignedRect(opt.direction, Qt::AlignCenter/*index.data(Qt::TextAlignmentRole).value<Qt::Alignment>()*/, iconRect.size(), opt.rect); QIcon::Mode mode = QIcon::Normal; if (!(opt.state & QStyle::State_Enabled)) mode = QIcon::Disabled; else if (opt.state & QStyle::State_Selected) mode = QIcon::Selected; QIcon::State state = opt.state & QStyle::State_Open ? QIcon::On : QIcon::Off; opt.icon.paint(painter, iconRect, opt.decorationAlignment, mode, state); } else { QStyledItemDelegate::paint(painter, option, index); } } bool CenteredCheckBoxDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) { Q_ASSERT(event); Q_ASSERT(model); // make sure that the item is checkable Qt::ItemFlags flags = model->flags(index); if (!(flags & Qt::ItemIsUserCheckable) || !(option.state & QStyle::State_Enabled) || !(flags & Qt::ItemIsEnabled)) return false; // make sure that we have a check state QVariant value = index.data(Qt::CheckStateRole); if (!value.isValid()) return false; const QWidget *widget = option.widget; QStyle *style = option.widget ? widget->style() : QApplication::style(); // make sure that we have the right event type if ((event->type() == QEvent::MouseButtonRelease) || (event->type() == QEvent::MouseButtonDblClick) || (event->type() == QEvent::MouseButtonPress)) { QStyleOptionViewItem viewOpt(option); initStyleOption(&viewOpt, index); QRect checkRect = style->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &viewOpt, widget); checkRect = QStyle::alignedRect(viewOpt.direction, Qt::AlignCenter/*index.data(Qt::TextAlignmentRole).value<Qt::Alignment>()*/, checkRect.size(), viewOpt.rect); QMouseEvent *me = static_cast<QMouseEvent *>(event); if (me->button() != Qt::LeftButton || !checkRect.contains(me->pos())) return false; if ((event->type() == QEvent::MouseButtonPress) || (event->type() == QEvent::MouseButtonDblClick)) return true; } else if (event->type() == QEvent::KeyPress) { if (static_cast<QKeyEvent *>(event)->key() != Qt::Key_Space && static_cast<QKeyEvent *>(event)->key() != Qt::Key_Select) return false; } else { return false; } Qt::CheckState state = static_cast<Qt::CheckState>(value.toInt()); if (flags & Qt::ItemIsUserTristate) state = ((Qt::CheckState)((state + 1) % 3)); else state = (state == Qt::Checked) ? Qt::Unchecked : Qt::Checked; return model->setData(index, state, Qt::CheckStateRole); }
Thanks everyone who took part in the discussion.