How to adjust QTextEdit to fit it's contents
Asked Answered
N

5

9

I'm developing a Qt Application and I'm trying to find a way to use QTextEdit as a label with long text without the scroll bar. In my ui I have a QScrollArea and inside of it I want to place a couple off QTextEdit widgets and I only want use scrolling inside QScrollArea. Problem is that no matter how I try to resize the QTextEdit it seems it has a maximum height and cuts of text, even if I set the size manually and QTextEdit::size returns the correct value.

I did the same thing with QLabel and it works fine, but in this case I need some methods that are only provided in QTextEdit.

I found this post: Resizing QT's QTextEdit to Match Text Height: maximumViewportSize()

And the answer given was the following:

I have solved this issue. There were 2 things that I had to do to get it to work:

  1. Walk up the widget hierarchy and make sure all the size policies made sense to ensure that if any child widget wanted to be big/small, then the parent widget would want to be the same thing.
  2. This is the main source of the fix. It turns out that since the QTextEdit is inside a QFrame that is the main widget in a QScrollArea, the QScrollArea has a constraint that it will not resize the internal widget unless the "widgetResizable" property is true. The documentation for that is here: http://doc.qt.io/qt-4.8/qscrollarea.html#widgetResizable-prop. The documentation was not clear to me until I played around with this setting and got it to work. From the docs, it seems that this property only deals with times where the main scroll area wants to resize a widget (i.e. from parent to child). It actually means that if the main widget in the scroll area wants to ever resize (i.e. child to parent), then this setting has to be set to true. So, the moral of the story is that the QTextEdit code was correct in overriding sizeHint, but the QScrollArea was ignoring the value returned from the main frame's sizeHint.

The problem is that I have no idea how to access the QTextEdit's QScrollArea to enable widgetResizable. Can anyone explain how I can achieve this or suggest a different way of resizing QTextEdit to perfectly fit it's content?

Noenoel answered 8/12, 2017 at 8:24 Comment(0)
F
3

Try this one :

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());
Frottage answered 8/12, 2017 at 9:34 Comment(1)
In Python, Pyside 2, Qt 5.6.1 idealWidth() returns -1 in my case. This may be related to using the no wrap flag but I didn't check. The docs just say textWidth defaults to -1 and I am assuming this is related. Perhaps when -1 use something else.Clearing
G
3

This will allow the height of the text box to change as required. You can edit the code a little to handle the width as well.

connect( m_textField, SIGNAL( textChanged() ), this, SLOT( onTextChanged() ) );

void MyClass::onTextChanged()
{
  QSize size = m_textField->document()->size().toSize();

  m_textField->setFixedHeight( size.height() + 3 );
}
Granular answered 27/6, 2018 at 13:8 Comment(5)
This didn't work for me - when the content of the box was refreshed, the size oscillated between two heights, even though the text was unchanged.Indestructible
not working, height is always zeroPankey
not working for meArchaeopteryx
This works for me, if it does not work for anyone, make sure the QTextEdit widget is visible and shown on the screen before adjusting its size. It the editor is not shown on the screen and you try to use this, it will not work (it didn't for me) but if your run the code after you show() the QTextEdit, it does work.Drusilla
Size seems to be the number of rows for me, so it should be multiplied by line height? (Using QPlainTextEdit)Kavita
R
1

Without a concrete example it's difficult to judge, but... it sounds as if you simply want a QTextEdit whose sizeHint depends on the current document size.

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);
    }
};

Then use as...

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

It appears to work as expected in the few tests I've done.

Ratsbane answered 8/12, 2017 at 9:45 Comment(0)
F
0

In ui i defined QTextEdit *textEdit object. I write it as height scalable-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));

Notice : this work if you change QTextEdit font face or size! just in height scalable (before every thing set your QTextEdit frameShape to BOX).

if you want do width scalable-content, you should do these steps :

  • read QTextEdit(textEdit object) text as line to line
  • calculate every line length
  • select maximum of line length
  • use of QTextEdit::fontMetrics().width(QString str) for investigate str size in width

I hope this can help you...

Frottage answered 8/12, 2017 at 9:7 Comment(3)
Thanks for answering, the problem is that first off all I don't have "\n" new line characters - The text is word wrapped. Secondly the problem is that even if I know the correct size, there is a point at which QTextEdit just provides a scrollbar instead of getting bigger - and that's my issue.Noenoel
@Noenoel can you disable scroll-bar peroperty in any way?Sawtelle
Yes, by setting : textEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff), but this doesn't change the fact that some of the text is cut off.Noenoel
E
0

I make it work in my case:

content_height = field.document().lineCount() * 30
field.setFixedHeight(content_height)
frame.setFixedHeight(content_height + 12)

where "field" is the QTextEdit added to the layout of the hosting QFrame "frame".

Eusebiaeusebio answered 31/8, 2023 at 3:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.