I have an issue with text elide in Qt being too aggressive in a table, see picture.
The cell with the full figure 0.8888.... I've edited since the QTableWidget was shown, the others are are as the were when the QTableWidget was created. It seems like the elide is calculated on a lesser width that is actually the case. How can I prevent this and get proper text elide immediately when the widget becomes visible?
Simplifide code to reproduce:
QTableWidget *tableWidget;
tableWidget = new QTableWidget(Dialog);
tableWidget->setGeometry(QRect(40, 20, 256, 192));
tableWidget->setRowCount(4);
tableWidget->setColumnCount(1);
tableWidget->setItem(0, 0, new QTableWidgetItem("0.234823489789234"));
and result
Note that I would like to avoid doing the elide myself since the user can edit the value. Doing the elide myself would then mean putting back the real value when editing starts, perhaps via delegates. Would be complicated.
...the solution could have been as simple as disabling the elide in the QTableWidget
and set directly an elided string as item's text like that:
tableWidget->setTextElideMode(Qt::ElideNone);
tableWidget->setItem(0, 0, new QTableWidgetItem(tableWidget->fontMetrics().elidedText("0.234823489789234", Qt::ElideRight, tableWidget->columnWidth(0))));
Unfortunately, QTableWidget
(or maybe it is QStyledItemDelegate
) does not respect the QAbstractItemView::textElideMode
property.
Thus, you need to do it the hard way, i.e. using delegates. Do not worry though, it is not much more complicated.
Subclass QStyledItemDelegate
and reimplement its paint
method like this:
void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
if (!index.isValid())
return;
QStyleOptionViewItem opt = option;
initStyleOption(&opt, index);
int padding = 3;
painter->save();
painter->setClipRect(opt.rect);
opt.rect = opt.rect.adjusted(padding, padding, -padding, -padding);
painter->drawText(opt.rect, Qt::AlignLeft | Qt::AlignVCenter,
opt.fontMetrics.elidedText(opt.text, Qt::ElideRight,
opt.rect.width()));
painter->restore();
opt.rect = option.rect;
opt.textElideMode = Qt::ElideNone;
opt.text = "";
QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &opt, painter);
}
Feel free to change the padding to a suitable value.
Set the tableWidget
's delegate for the desired column like this:
tableWidget->setItemDelegateForColumn(0, new Delegate(this));
where Delegate
is your QStyledItemDelegate
subclass.
The result of this modification is a column with a properly elided text.