How to force layout update/resize when child it manages resizes?

前端 未结 2 1933
粉色の甜心
粉色の甜心 2021-02-07 09:31

I have a custom QTextEdit widget that has it\'s own resize grip in the corner. I can resize the text widget fine, however the layout it is inside does not change wi

相关标签:
2条回答
  • 2021-02-07 09:44

    The answer of leemes gave me some insight and I managed to achieve resize of a QTextWidget inside a layout among other controls using custom SizeGrip control. Note that at least one scroll bar should be visible in order to have visible size grip.

    It was necessary to reimplement the widget's sizeHint() method:

    QSize MultilineTextEdit::sizeHint() const
    {
        return size();
    }
    

    Then at the end of mouseMoveEvent() of my SizeGrip widget I added

    void SizeGrip::mouseMoveEvent(QMouseEvent * e)
    {
        // note that this is not the full code of the method
        ...
        // save the old minimum and maximum size of the widget (w) resized by the grip
        QSize oldMin = w->minimumSize();
        QSize oldMax = w->maximumSize();
    
        w->setFixedSize(nr.size()); // nr is the new rect of the widget
    
        w->setMinimumSize(oldMin);
        w->setMaximumSize(oldMax);
    }
    

    The SizeGrip widget was inspired by the QSizeGrip class which operates on the top level parent window directly. SizeGrip operates on its direct parent widget instead.

    0 讨论(0)
  • 2021-02-07 10:00

    The layout respects the sizeHint() and minimalSizeHint() of its children (not their size()). So you should reimplement these two virtual methods and return the size you want to force. Whenever your size hint changes, you should call updateGeometry() on your own widget to trigger an update of the layout where the widget is placed in.

    See documentation:

    • virtual QSize QWidget::sizeHint() const

      This property holds the recommended size for the widget.
      [...]

    • virtual QSize QWidget::minimumSizeHint() const

      This property holds the recommended minimum size for the widget.
      [...]
      QLayout will never resize a widget to a size smaller than the minimum size hint unless minimumSize() is set or the size policy is set to QSizePolicy::Ignore. If minimumSize() is set, the minimum size hint will be ignored.

    So, to force a minimum size of your widget, implement minimumSizeHint() by returning your minimum size; to force a fixed size, implement both by returning the same size.

    I also recommend reading the following section in the documentation page "Layout Management":

    Custom Widgets in Layouts

    When you make your own widget class, you should also communicate its layout properties. If the widget has a one of Qt's layouts, this is already taken care of. If the widget does not have any child widgets, or uses manual layout, you can change the behavior of the widget using any or all of the following mechanisms:

    • Reimplement QWidget::sizeHint() to return the preferred size of the widget.
    • Reimplement QWidget::minimumSizeHint() to return the smallest size the widget can have.
    • Call QWidget::setSizePolicy() to specify the space requirements of the widget.

    Call QWidget::updateGeometry() whenever the size hint, minimum size hint or size policy changes. This will cause a layout recalculation. Multiple consecutive calls to QWidget::updateGeometry() will only cause one layout recalculation.


    Update (see comments):

    You can also force a size (or height / width only) by calling:

    QWidget::setFixedSize(QSize);
    QWidget::setFixedHeight(int);
    QWidget::setFixedWidth(int);
    

    These methods simply set the size hints to the given value and call updateGeometry() AFAIK. But maybe they do a little bit more since (as seen in the comments) this was the only way I could find to solve the problem here.

    0 讨论(0)
提交回复
热议问题