Search code examples
python-3.xqtpyqt5qgridlayout

How to reserve space for hidden QtWaitingSpinner in QGridLayout?


I'm trying to build a QtGui application that uses the QtWaitingSpinner found here: https://github.com/z3ntu/QtWaitingSpinner. I have it in a QGridLayout. However, this means that the button next to it changes size when the spinner is unhidden and started. How do I reserve the correct amount of space for the spinner in the grid so that the button next to it stays a constant size regardless of whether the spinner is shown?

Based on this stackoverflow post How to use spacers in Qt, I suspect that the answer involves QSpacerItem. However, I can't figure out how to size the QSpacerItem based on the size the spinner will need.

Here's a minimal example of the code to show my problem:

import PyQt5.QtWidgets as QWidgets
import PyQt5.QtCore as QtCore
import PyQt5.QtGui as QtGui
from waitingspinnerwidget import QtWaitingSpinner
import sys

class Example_Window(QWidgets.QWidget):
    def __init__(self):
        super(QWidgets.QWidget,self).__init__()
        self.initUI()

    def initUI(self):
        self.button=QWidgets.QPushButton("Start/Stop Spinner")
        self.button.clicked.connect(self.toggle_spinner)
        self.spinner = QtWaitingSpinner(self,centerOnParent=False)
        self.grid = QWidgets.QGridLayout()
        self.grid.addWidget(self.button,0,0)
        self.grid.addWidget(self.spinner,0,1)
        self.setLayout(self.grid)
        self.show()

    def toggle_spinner(self):
        if self.spinner.isSpinning():
            self.spinner.stop()
        else:
            self.spinner.start()

if __name__ == '__main__':
    app = QWidgets.QApplication([])
    main = Example_Window()
    sys.exit(app.exec())    

Solution

  • Try it:

    import PyQt5.QtWidgets as QWidgets
    import PyQt5.QtCore as QtCore
    import PyQt5.QtGui as QtGui
    from waitingspinnerwidget import QtWaitingSpinner
    import sys
    
    class Example_Window(QWidgets.QWidget):
        def __init__(self):
            super(QWidgets.QWidget,self).__init__()
    
            self.initUI()
    
        def initUI(self):
            self.button = QWidgets.QPushButton("Start Spinner") # +
            self.button.clicked.connect(self.toggle_spinner)
    
            self.spinner = QtWaitingSpinner(self, centerOnParent=False)
    
            self.grid = QWidgets.QGridLayout()
            self.grid.addWidget(self.button, 0, 0)
    
    #        self.grid.addWidget(self.spinner,0,1)        # ---
            self.grid.addWidget(self.spinner, 0, 1, 1, 2) # +++    <---
    
            self.setLayout(self.grid)
            self.show()
    
        def toggle_spinner(self):
            if self.spinner.isSpinning():
                self.spinner.stop()
                self.button.setText("Start Spinner") # +
            else:
                self.spinner.start()
                self.button.setText("Stop Spinner")  # +
    
    if __name__ == '__main__':
        app = QWidgets.QApplication([])
        main = Example_Window()
        main.resize(170, 70)                               # +++
        sys.exit(app.exec())    
    

    enter image description here