Amin Mesbah
Amin Mesbah

Reputation: 872

PyQt5 grid layout expands for big widgets, but doesn't contract for small widgets

Question: How can I make a PyQt grid layout shrink when the size of a widget decreases?

Desired Behavior

Display a long string in a label in a PyQt grid layout. The grid expands to accomodate the label. When the label is reset to a shorter string, the grid, no longer needing the extra space, contracts.

Actual Behavior

The grid expands to accomodate a long label, but doesn't contract when the label becomes shorter. It remains at its expanded size.

Initial State

Initial state

Displaying the long label

Displaying the long label

Grid stays expanded after label is cleared

Grid stays expanded after the label is cleared

Minimal example using PyQt5 (5.7) in Python 3.5

The example below includes two buttons and a label. One button sets the label to 400 character long string of asterisks. The other sets the label to the empty string.

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (
    QApplication,
    QGridLayout,
    QLabel,
    QPushButton,
    QWidget,
)


class TestUI(QWidget):

    def __init__(self):
        super().__init__()
        self.lbl_feedback = QLabel('Long string goes here', self)

        btn_long_string = QPushButton('Display a long string', self)
        btn_long_string.clicked.connect(self._show_feedback_label)

        btn_clear = QPushButton('Clear the long string', self)
        btn_clear.clicked.connect(self._hide_feedback_label)

        grid = QGridLayout()
        grid.setSpacing(5)

        # assemble grid
        grid.addWidget(self.lbl_feedback, 0, 1, Qt.AlignCenter)
        grid.addWidget(btn_long_string, 1, 1, Qt.AlignCenter)
        grid.addWidget(btn_clear, 2, 1, Qt.AlignCenter)

        # resize weights
        grid.setColumnStretch(0, 10)
        grid.setColumnStretch(1, 10)
        grid.setColumnStretch(2, 10)

        self.setLayout(grid)
        self.show()

    def _show_feedback_label(self):
        long_string = '*' * 400
        self.lbl_feedback.setText(long_string)

    def _hide_feedback_label(self):
        self.lbl_feedback.setText('')


if __name__ == '__main__':
    app = QApplication(sys.argv)
    test_ui = TestUI()
    sys.exit(app.exec_())

Upvotes: 3

Views: 1192

Answers (1)

ADR
ADR

Reputation: 1291

I think it is impossible for main window because i can't find it in Qt Designer. But you can call mainwindow.adjustSize() on label.changed signal.

Update: Sorry, I was wrong. QLabel has no "changed" signal. Other way:

def _hide_feedback_label(self):
    self.lbl_feedback.setText('')

    self.adjustSize() # <--

Upvotes: 2

Related Questions