【问题标题】:How to adjust QTextEdit to fit it's contents如何调整 QTextEdit 以适应其内容
【发布时间】:2018-05-22 11:04:46
【问题描述】:

我正在开发一个 Qt 应用程序,我正在尝试找到一种方法将 QTextEdit 用作 label 并带有长文本而没有滚动条。在我的用户界面中,我有一个QScrollArea,在其中我想放置几个关闭QTextEdit 小部件,我只想在QScrollArea 内使用滚动。问题是,无论我如何尝试调整 QTextEdit 的大小,它似乎都有最大高度和文本剪切,即使我手动设置大小并且 QTextEdit::size 返回正确的值。

我对@9​​87654329@ 做了同样的事情,它工作正常,但在这种情况下,我需要一些仅在QTextEdit 中提供的方法。

我发现了这个帖子: Resizing QT's QTextEdit to Match Text Height: maximumViewportSize()

给出的答案如下:

我已经解决了这个问题。我必须做两件事才能得到 它的工作:

  1. 查看小部件层次结构并确保制定了所有尺寸策略 确保如果任何子小部件想要大/小,那么 父小部件希望是同一件事。
  2. 这是主要的 修复的来源。事实证明,由于 QTextEdit 在 QFrame 是 QScrollArea 中的主要小部件,QScrollArea 有一个 约束它不会调整内部小部件的大小,除非 “widgetResizable”属性为真。文档是 在这里:http://doc.qt.io/qt-4.8/qscrollarea.html#widgetResizable-prop。 在我玩弄这个之前,我并不清楚文档 设置并让它工作。从文档看来,这个属性 仅处理主滚动区域想要调整大小的时间 小部件(即从父级到子级)。这实际上意味着如果主 滚动区域中的小部件想要调整大小(即从子到父), 那么这个设置必须设置为true。所以,这个故事的寓意是 QTextEdit 代码在覆盖 sizeHint 时是正确的,但是 QScrollArea 忽略了从主框架返回的值 大小提示。

问题是我不知道如何访问QTextEdit's QScrollArea 来启用widgetResizable。谁能解释我如何实现这一点或建议调整QTextEdit 大小以完全适合其内容的不同方式?

【问题讨论】:

  • 你不能访问QTextEdit的QScrollArea,因为它不是QScrollArea,它继承自没有setWidgetResizable标志的QAbstractScrollArea

标签: c++ qt resize qtextedit qscrollarea


【解决方案1】:

在ui 中,我定义了QTextEdit *textEdit 对象。我把它写成heightscalable-content:

int count = 0;
QString str = "";

// set textEdit text
ui->textEdit->setText("hfdsf\ncsad\nfsc\dajkjkjkjhhkdkca\n925");
str = ui->textEdit->toPlainText();

for(int i = 0;i < str.length();i++)
    if(str.at(i).cell() == '\n')
        count++;

// resize textEdit (width and height)
ui->textEdit->resize(ui->textEdit->fontMetrics().width("this is the max-length line in qlabel")
         , ui->textEdit->fontMetrics().height() * (count + 2));

注意:如果您更改QTextEdit 字体或大小,则此工作!高度可扩展(在每件事之前将您的QTextEdit frameShape 设置为BOX)。

如果你想做宽度可缩放的内容,你应该做这些步骤:

  • 逐行读取QTextEdit(textEdit object) 文本
  • 计算每行长度
  • 选择最大行长
  • 使用QTextEdit::fontMetrics().width(QString str) 调查str 宽度尺寸

希望对你有帮助...

【讨论】:

  • 感谢您的回答,问题是首先我没有“\n”换行符 - 文本是自动换行的。其次,问题是,即使我知道正确的大小,QTextEdit 有时也只是提供一个滚动条而不是变得更大——这就是我的问题。
  • @madasionka 你能以任何方式disable滚动条操作吗?
  • 是的,通过设置:textEdit-&gt;setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff),但这并不会改变某些文本被截断的事实。
【解决方案2】:

试试这个:

QTextEdit textEdit;
textEdit.setHtml("<p>test test test test test test</p><p>|||||||||</p>");
textEdit.show();
textEdit.setFixedWidth(textEdit.document()->idealWidth() +
                       textEdit.contentsMargins().left() +
                       textEdit.contentsMargins().right());

【讨论】:

  • 在 Python 中,Pyside 2,Qt 5.6.1 IdealWidth() 在我的情况下返回 -1。这可能与使用 no wrap 标志有关,但我没有检查。文档只是说 textWidth 默认为 -1,我假设这是相关的。也许当 -1 使用其他东西时。
【解决方案3】:

如果没有具体的例子,很难判断,但是...听起来好像您只是想要一个QTextEdit,其sizeHint 取决于当前文档的大小。

class text_edit: public QTextEdit {
  using super = QTextEdit;
public:
  explicit text_edit (QWidget *parent = nullptr)
    : super(parent)
    {
      setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
      setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
      setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    }
  virtual QSize sizeHint () const override
    {
      QSize s(document()->size().toSize());

      /*
       * Make sure width and height have `usable' values.
       */
      s.rwidth() = std::max(100, s.width());
      s.rheight() = std::max(100, s.height());
      return(s);
    }
protected:
  virtual void resizeEvent (QResizeEvent *event) override
    {

      /*
       * If the widget has been resized then the size hint will
       * also have changed.  Call updateGeometry to make sure
       * any layouts are notified of the change.
       */
      updateGeometry();
      super::resizeEvent(event);
    }
};

然后用作...

QScrollArea sa;
sa.setWidgetResizable(true);
text_edit te;
te.setPlainText(...);
sa.setWidget(&te);
sa.show();

它似乎在我完成的几个测试中按预期工作。

【讨论】:

    【解决方案4】:

    这将允许文本框的高度根据需要更改。您也可以稍微编辑代码以处理宽度。

    connect( m_textField, SIGNAL( textChanged() ), this, SLOT( onTextChanged() ) );
    
    void MyClass::onTextChanged()
    {
      QSize size = m_textField->document()->size().toSize();
    
      m_textField->setFixedHeight( size.height() + 3 );
    }
    

    【讨论】:

    • 这对我不起作用 - 当框的内容被刷新时,大小在两个高度之间波动,即使文本没有改变。
    • 不工作,高度始终为零
    猜你喜欢
    • 2021-09-16
    • 1970-01-01
    • 2021-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-22
    • 1970-01-01
    相关资源
    最近更新 更多