6
votes

I have a custom widget which has an overall layout of a QVBoxLayout. It contains several labels, a QFormLayout, a button, and a stretch to eat all excess space. One of the labels can be quite large so I am trying to ensure that there are no odd cases where the text is unreadable. The widget is contained within a QScrollArea to ensure that if the user shrinks the overall window all aspects of the widget can still be seen.

The QLabel appears to resize fine, but once it reaches a certain point of narrowness it just cuts off the bottom few lines of the label and allocates the space to the stretch at the bottom of the widget.

I am doing this all in code without the Designer, so it is entirely possible that I am just missing something. The subcomponents are added to the overall QVBoxLayout in the following order:

OverallLayout = new QVBoxLayout(this);
Title         = new QLabel();
Description   = new QLabel();
SubRegion     = new QFormLayout();
Button        = new QButton();
...
// set text values, wordWrap(true), and Font for labels
OverallLayout->addWidget(Title);
OverallLayout->addWidget(Description);
OverallLayout->addLayout(SubRegion);
OverallLayout->addStrut(MIN_DIST);
OverallLayout->addWidget(Button);
OverallLayout->addStretch(STRETCH_FACTOR);

Test results: Examining the results returned from the QLabel's sizeHint() function, the values returned do not appear to change as the widget is shrunk horizontally. However, the QLabel does expand to take up more vertical room (153 vs the hint of 103), just not enough to fit all of the text. When the QLabel is first shown, it has less pixels than its sizeHint but still enough for its heightForWidth amount. When it is resized, it has 30 less than its heightForWidth amount but more than its sizeHint.

I have checked and the large QLabel has its hasHeightForWidth() and wordWrap() values set to true. What am I doing wrong?

1
Could you add the code snippet where these widgets are being added to the layout? I think that you should set the minimum size of QLabel by setMinimumHeight() so that there is no cut-off. Alternatively you can set a max height value for the spacer element.fatma.ekici
One way I thought of fixing it is linking to the resized method and having the minimum height set to the heightForWidth(width) value for the Description label. This seems a bit kludgey though, so I was wondering what the proper way to get the layout manager to do its job would be.ElCraneo
But what about the suggestion to use setMinimumHeight() ?jdi
I am currently doing that by intercepting the resizeEvent, computing the heightForWidth of the new width, then doing setMinimumHeight(). However, this seems kludgy (as per my previous comment) and I was trying to find a way that Qt would handle this on its own. Is it something I am doing wrong in my initialization or is intercepting the resizeEvent really the optimum way to fix this?ElCraneo

1 Answers

3
votes

I ended up going with the method of overwriting the widget's resizeEvent(QResizeEvent *evt) function in order to set the maximum value of the QLabel dynamically.

void MyWidget::resizeEvent (QResizeEvent *evt) {
   int newHeight = Description.heightForWidth(Description.width());
   Description.setMaximumHeight(newHeight);
   QWidget::resizeEvent(evt); 
   // Note: I'm not sure if this last step is necessary
}

An interesting item to note is that if you do both setMinimumHeight(newHeight) and setMaximumHeight(newHeight) the label will grow vertically to fit the text but it will never shrink when the label grows horizontally and doesn't need the extra space. My guess is that heightForWidth(int w) returns the max between the widget's minimumHeight and the pixels actually needed. The odd part is that it doesn't seem to care about returning a value larger than the current maximumHeight.