QComboBox选中项的省略文本

4

所以,我有一个 QComboBox

enter image description here

如果currentText()对于小部件来说太长,那么我想显示省略号。
就像这样:

enter image description here

所以:

void MyComboBox::paintEvent(QPaintEvent * )
{
      QStylePainter painter(this);
      QStyleOptionComboBox opt;
      initStyleOption(&opt);
      painter.drawComplexControl(QStyle::CC_ComboBox, opt);

      QRect rect = this->rect();
      //this is not ideal
      rect.setLeft(rect.left() + 7);
      rect.setRight(rect.width() - 15);
      //

      QTextOption option;
      option.setAlignment(Qt::AlignVCenter);

      QFontMetrics fontMetric(painter.font());
      const QString elidedText = QAbstractItemDelegate::elidedText(fontMetric, rect.width(), Qt::ElideRight, this->currentText());
      painter.drawText( rect, elidedText, option);
}

这完美地工作着。

问题在于注释之间的代码,因为我正在硬编码左右边框的距离。这让我感到不舒服。

没有那段代码的结果是:

enter image description here

有没有人知道一种更通用的方法来做到这一点,而不是硬编码?谢谢

2个回答

3

文本应该放在哪里取决于所使用的样式。您可以使用QStyle::subControlRect获得有关子元素定位的信息。似乎最符合组合框文本的子控件是QStyle::SC_ComboBoxEditField,但如果项目具有图标,则还需要考虑这一点。如果项目没有图标,您可以使用:

  QRect textRect = style()->subControlRect(QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxEditField, this);
  QFontMetrics fontMetric(painter.font());
  const QString elidedText = QAbstractItemDelegate::elidedText(fontMetric, textRect.width(), Qt::ElideRight, this->currentText());
  opt.currentText = elidedText;
  painter.drawControl(QStyle::CE_ComboBoxLabel, opt);

如果您想详细了解如何运作例如QFusionStyle::drawControl,请参考相关内容。

如果您希望所有下拉框都能省略文字,您可以考虑实现自己的QProxyStyle并仅针对QStyle::CE_ComboBoxLabel覆盖MyStyle::drawControl


谢谢您的建议。我一有时间就会尝试调查您所建议的内容! - andrea.marangoni

2

这是我一直在使用的解决方案:

void CustomComboBox::paintEvent(QPaintEvent * /*event*/)
{
    QStyleOptionComboBox opt;
    initStyleOption(&opt);

    QStylePainter p(this);
    p.drawComplexControl(QStyle::CC_ComboBox, opt);

    QRect textRect = style()->subControlRect(QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxEditField, this);
    opt.currentText = p.fontMetrics().elidedText(opt.currentText, Qt::ElideRight, textRect.width());
    p.drawControl(QStyle::CE_ComboBoxLabel, opt);
}

这种方法与您的示例代码和E4z9建议的片段非常相似。我只是想为以后来到这里的其他人包含整个方法。"最初的回答"

1
尝试了这种方法,调试输出显示了正确的初始文本并且被正确省略了,但在用户界面中仍然显示初始的未被省略的文本。更奇怪的是,如果我注释掉整个方法体内容,标签仍然被绘制,除了标签上的非省略文本之外,没有其他任何东西,没有按钮,也没有组合框的框架。我错过了什么吗? - Damir Porobic
1
@DamirPorobic,我刚刚检查了一下,上面的实现正是我们已经运送了多年而没有任何报告问题的。如果您注释掉paintEvent的主体,那么小部件将不会被绘制,这意味着您看到的任何绘制都必须来自其他地方。 - Parker Coates
这将更改弹出窗口中项目的文本,而不是当弹出窗口隐藏时显示的LineEdit文本。 - W.Perrin
@W.Perrin,这是基于一个不可编辑的QComboBox的假设。我想不出有什么明智的方法可以(或者想要)在QLineEdit内部省略文本。 - Parker Coates

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接