如何防止 QTableview 中过于激进的文本省略?
How to prevent too aggressive text elide in QTableview?
我有一个问题,Qt 中的文本省略在 table 中过于激进,见图。
全图0.8888的单元格....自从显示QTableWidget后我就编辑了,其他的和创建QTableWidget时一样。似乎 elide 是在实际情况下的较小宽度上计算的。当小部件变得可见时,如何防止这种情况并立即删除适当的文本?
简化重现代码:
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"));
和结果
请注意,我想避免自己删除,因为用户可以编辑该值。自己做 elide 意味着在编辑开始时放回真实值,也许是通过委托。会很复杂。
当一切正常时...
...解决方案可以像禁用 QTableWidget
中的省略号并直接将省略的字符串设置为项目的文本一样简单:
tableWidget->setTextElideMode(Qt::ElideNone);
tableWidget->setItem(0, 0, new QTableWidgetItem(tableWidget->fontMetrics().elidedText("0.234823489789234", Qt::ElideRight, tableWidget->columnWidth(0))));
不幸的是,QTableWidget
(或者可能是QStyledItemDelegate
)不尊重QAbstractItemView::textElideMode
属性.
因此,您需要用困难的方式来做到这一点,即使用委托。不过别担心,它并不复杂。
解决方案
子类 QStyledItemDelegate
并像这样重新实现它的 paint
方法:
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);
}
随意将填充更改为合适的值。
像这样为所需列设置 tableWidget
的委托:
tableWidget->setItemDelegateForColumn(0, new Delegate(this));
其中 Delegate
是您的 QStyledItemDelegate
子类。
结果
此修改的结果是一个包含正确省略文本的列。
我有一个问题,Qt 中的文本省略在 table 中过于激进,见图。
全图0.8888的单元格....自从显示QTableWidget后我就编辑了,其他的和创建QTableWidget时一样。似乎 elide 是在实际情况下的较小宽度上计算的。当小部件变得可见时,如何防止这种情况并立即删除适当的文本?
简化重现代码:
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"));
和结果
请注意,我想避免自己删除,因为用户可以编辑该值。自己做 elide 意味着在编辑开始时放回真实值,也许是通过委托。会很复杂。
当一切正常时...
...解决方案可以像禁用 QTableWidget
中的省略号并直接将省略的字符串设置为项目的文本一样简单:
tableWidget->setTextElideMode(Qt::ElideNone);
tableWidget->setItem(0, 0, new QTableWidgetItem(tableWidget->fontMetrics().elidedText("0.234823489789234", Qt::ElideRight, tableWidget->columnWidth(0))));
不幸的是,QTableWidget
(或者可能是QStyledItemDelegate
)不尊重QAbstractItemView::textElideMode
属性.
因此,您需要用困难的方式来做到这一点,即使用委托。不过别担心,它并不复杂。
解决方案
子类
QStyledItemDelegate
并像这样重新实现它的paint
方法: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); }
随意将填充更改为合适的值。
像这样为所需列设置
tableWidget
的委托:tableWidget->setItemDelegateForColumn(0, new Delegate(this));
其中 Delegate
是您的 QStyledItemDelegate
子类。
结果
此修改的结果是一个包含正确省略文本的列。