Python Forum

Full Version: QGridLayout, QProgressBar bar fills widgets shrink
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I have a QGridLayout with some QLabels and QLineEdits and a QProgressBar. As the progress bar fills, the QLineEdits shrink. What's up with that. Code:
wnd_grid, wnd_edit = QGridLayout(), QTextEdit()
prog = QProgressBar
header = ['To:', 'CC:', 'BCC:', 'Subject:']
edits = [QLineEdit(), QLineEdit(), QLineEdit(), QLineEdit()]
for i, (lab, lin) in enumerate(zip(header, edits)):
    wnd_grid.addWidget(W.QLabel(lab), i, 0)
    wnd_grid.addWidget(lin, i, 1, 1, 5)
wnd_grid.addWidget(wnd_edit, 4, 0, 1, 6)
wnd_grid.addWidget(prog, 5, 1)
Standard stuff. I just don't know why growing progress shrinks a column space? These widgets are set in a QMainWindow with a frame as the central widget, then the GridLayout's parent is the frame. Obviously, the QMainWindow has a layout by default, so I can't add a second. It has a central widget, but can I set another widget (like a frame), and then set another layout to house the progressbar. I'm just thinking separating the PB from the layout with Line Edits. Is there something else I can do?
Well, I posted prior to any real attempt to solve this problem on my own. I fixed it with a different approach. By using a VBoxLayout as my main layout, and then nesting HBoxLayout's with the necessary widgets, the problem is gone.

If anyone has any idea about the grid issue, I'd like to hear a solution or potential solution.
like this?

from PyQt5.QtWidgets import (QMainWindow, QApplication, QGridLayout, QTextEdit, 
                             QProgressBar, QLineEdit, QLabel, QWidget, QPushButton)

class MainWindow(QMainWindow):
    def __init__(self, parent = None):
        super(MainWindow, self).__init__(parent)
        self.setupUI()
        
    def setupUI(self):
        self.setGeometry(0, 0, 700, 500)
        central_widget = QWidget()
        wnd_grid, wnd_edit = QGridLayout(), QTextEdit()
        self.prog = QProgressBar()
        header = ['To:', 'CC:', 'BCC:', 'Subject:']
        edits = [QLineEdit(), QLineEdit(), QLineEdit(), QLineEdit()]
        for i, (lab, lin) in enumerate(zip(header, edits)):
            wnd_grid.addWidget(QLabel(lab), i, 0)
            wnd_grid.addWidget(lin, i, 1, 1, 5)
        wnd_grid.addWidget(wnd_edit, 4, 0, 1, 6)
        wnd_grid.addWidget(self.prog, 5, 0, 1, 6)

        button = QPushButton()
        button.setText("Send")
        button.setFixedWidth(80)
        button.clicked.connect(self.update)
        wnd_grid.addWidget(button, 6, 0)
        
        central_widget.setLayout(wnd_grid)
        self.setCentralWidget(central_widget)
        
        
        
    def update(self):
        self.reset()
        completed = 0
     
        while completed < 100:
            completed += 0.00005
            self.prog.setValue(int(completed))
  
    def reset(self):
        value = 0
        self.prog.setValue(value)

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    win = MainWindow()
    win.setWindowTitle("Main Window")
    win.show()

    sys.exit(app.exec_())
or you can add a layout to the central_widget laylout

from PyQt5.QtWidgets import (QMainWindow, QApplication, QGridLayout, QTextEdit, QVBoxLayout, 
                             QProgressBar, QLineEdit, QLabel, QWidget, QPushButton)

class MainWindow(QMainWindow):
    def __init__(self, parent = None):
        super(MainWindow, self).__init__(parent)
        self.setupUI()
        
    def setupUI(self):
        self.setGeometry(0, 0, 700, 500)
        central_widget = QWidget()
        wnd_grid, wnd_edit = QGridLayout(), QTextEdit()
        self.prog = QProgressBar()
        header = ['To:', 'CC:', 'BCC:', 'Subject:']
        edits = [QLineEdit(), QLineEdit(), QLineEdit(), QLineEdit()]
        for i, (lab, lin) in enumerate(zip(header, edits)):
            wnd_grid.addWidget(QLabel(lab), i, 0)
            wnd_grid.addWidget(lin, i, 1, 1, 5)
        wnd_grid.addWidget(wnd_edit, 4, 0, 1, 6)
        

        button = QPushButton()
        button.setText("Send")
        button.setFixedWidth(80)
        button.clicked.connect(self.update)
        wnd_grid.addWidget(button, 6, 0)
        
        central_widget.setLayout(wnd_grid)
        prog_layout = QVBoxLayout()
        prog_layout.addWidget(self.prog)
        central_widget.layout().addLayout(prog_layout, 7, 0, 1, 6)
        self.setCentralWidget(central_widget)
        
        
        
    def update(self):
        self.reset()
        completed = 0
     
        while completed < 100:
            completed += 0.00005
            self.prog.setValue(int(completed))
  
    def reset(self):
        value = 0
        self.prog.setValue(value)

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    win = MainWindow()
    win.setWindowTitle("Main Window")
    win.show()

    sys.exit(app.exec_())
You're pretty helpful with with PyQt, @Axel_Erfurt. I haven't run your code, but I know it will not exhibit my problem. However, looking at it, nothing jumps out as to why. Thanks, but I'll just stick with what I have now (VBoxLayout with nested HBoxLayout's).

My code works, and I guess that's all that matters. I'm not married to a GridLayout. There's no real advantage I'm aware of in my use case.
I don't see any problem with your original code. I just added the main window and frame, and some code to change the progress bar when you type in the QEditText widget. I don't see any lahout changes.
from PySide6.QtWidgets import QApplication, QMainWindow, QFrame, QLineEdit, QProgressBar, QLabel, QGridLayout, QTextEdit
from PySide6.QtCore import QTimer

class Window(QMainWindow):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        frame = QFrame()
        self.setCentralWidget(frame)
        layout = QGridLayout(frame)
        header = ['To:', 'CC:', 'BCC:', 'Subject:']
        edits = [QLineEdit(), QLineEdit(), QLineEdit(), QLineEdit()]
        for i, (lab, lin) in enumerate(zip(header, edits)):
            layout.addWidget(QLabel(lab), i, 0)
            layout.addWidget(lin, i, 1, 1, 5)

        self.edit = QTextEdit()
        self.prog = QProgressBar()
        layout.addWidget(self.edit, 4, 0, 1, 6)
        layout.addWidget(self.prog, 5, 1)

        timer = QTimer(self)
        timer.timeout.connect(self.update_progress)
        timer.start(100)

    def update_progress(self):
        self.prog.setValue(len(self.edit.toPlainText()))


app = QApplication()
window = Window()
window.show()
app.exec()
Odd. Must be the other parts of my app that I didn't extract for this board. It's a 13 module app, so, other stuff going on. It's laid out on a secondary (popup) QMainWindow, but it sure as piss shrinks my LineEdits. Doesn't matter though, I solved it.

Thanks, fellas.
Post working examples that demonstrate the problem. That way you know the code you are posting is the problem code.