5
votes

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?

4
You cannot access QTextEdit's QScrollArea because it is not a QScrollArea, it inherits from QAbstractScrollArea, which doesn't have a setWidgetResizable flagAKludges

4 Answers

4
votes

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

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());
2
votes

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.

0
votes

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...