Bow*_*one 5 c++ qt fontmetrics
QTableWidget如果用户搜索了某些内容,我将有一个自定义委托来突出显示匹配项。不幸的是,矩形位置通常并不真正适合。这发生在某些字符或短语上,或者取决于匹配项的数量或前导字符串的大小。我找不到造成此问题的特定原因。这是一个例子:
。
这是我的绘画例程(尝试修复该问题的所有反复试验都有些混乱):
void custom_delegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const{
const QTableWidget* table_widget = qobject_cast<const QTableWidget*>(qstyleoption_cast<const QStyleOptionViewItemV3*>(&option)->widget);
const int cell_width = table_widget->columnWidth(index.column());
// basic table cell rectangle
QRect rect_a = option.rect;
// adjust rectangle to match text begin
QStyle* style;
if(table_widget != 0){
style = table_widget->style();
}else{
style = QApplication::style();
}
const int text_horizontal_margin = style->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, table_widget) + 1;
QRect rect_b = rect_a.adjusted(text_horizontal_margin, 0, -text_horizontal_margin, 0);
// adjust rectangle to match text height
QFont cell_font = index.model()->data(index, Qt::FontRole).value<QFont>();
cell_font.setPointSize(9);
QFontMetrics fm(cell_font);
const int height = fm.height();
rect_b.setY(rect_a.y() + (rect_a.height() - height)/2);
rect_b.setHeight(height);
// displayed text
std::string cell_text = qstrtostr(fm.elidedText(index.model()->data(index, Qt::DisplayRole).toString(),Qt::ElideRight,rect_a.width()));
int found_pos = find_ci(cell_text, this->filter_string, 0);
int old_pos = 0;
int found_width = 0;
QRect rect_c = rect_b;
// find occurence of filter string in cell_text
while(found_pos != std::string::npos){
std::string front = cell_text.substr(0, found_pos);
rect_c.setX(rect_b.x() + fm.tightBoundingRect(QString::fromStdString(front)).width());
rect_c.setWidth(fm.width(QString::fromStdString(cell_text.substr(found_pos, this->filter_string.size()))));
painter->fillRect(rect_c, Qt::yellow);
old_pos = found_pos+1;
found_pos = find_ci(cell_text, this->filter_string, old_pos);
}
}
Run Code Online (Sandbox Code Playgroud)
注意: filter_string搜索的字符串find_ci只是用于std::string::find包含不区分大小写的包装,但在这里并不重要,因为此测试用例完全是小写,我std::string用于非qt的东西。
编辑:对于宽度计算我试过fm.tightBoundingRect().width(),fm.boundingRect.width()并fm.width()用不同的,但从来没有得到正确的结果。
我使用Qt 5.2
就我而言,我通过以下 hack 获得了所需的结果:
auto initialRect = fm.boundingRect(text);
auto improvedRect = fm.boundingRect(initialRect, 0, text);
Run Code Online (Sandbox Code Playgroud)
尚不完全清楚为什么另一个重载boundingRect返回正确的结果,但这可能只是偶然的,因为正如文档所述:
该函数返回的边界矩形比更简单的函数计算的边界矩形稍大
boundingRect()。此功能使用最大左右字体方位,这是多行文本正确对齐所必需的。此外,fontHeight()和lineSpacing()用于计算高度,而不是单个字符的高度。
您提出的方法width也会返回更大的结果,但它似乎不正确,因为它应该仅在您需要下一个单词的位置时使用:
[...]
width()返回到下一个字符串应绘制的位置的距离。
另外,有时是否将结果传递painter.device()给QFontMetrics构造函数也很重要。
| 归档时间: |
|
| 查看次数: |
1979 次 |
| 最近记录: |