Search code examples
qtpyqtpysideqprogressbar

Place the text in the middle of QProgressBar when setRange(0, 0) on Windows?


How to place text (not just a number) in the middle of QProgressBar when setRange(0, 0) on Windows?

The following is a PyQt example which still doesn't work as expected.

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *

class MainWindow(QMainWindow):

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.resize(800, 600)

#        self.lb=QLabel('finding resource   ')

        self.pb = QProgressBar()
        self.pb.setRange(0, 0)

        self.pb.setAlignment(Qt.AlignCenter)
        self.pb.setFormat('finding resource...')
        self.pb.setStyleSheet("text-align: center;")

#        self.pb.setTextVisible(False)


        self.statusBar().setSizeGripEnabled(False)
#        print(self.statusBar().layout() )
        self.statusBar().setStyleSheet("QStatusBar::item {border: none;}")
        self.statusBar().addPermanentWidget(self.pb, 1)


if __name__ == "__main__":
    app = QApplication(sys.argv)

    ui = MainWindow()
    ui.show()
    sys.exit(app.exec_())

Solution

  • vahancho explained the reason nicely in his answer and mentioned to override QProgressBar.text(). Fortunately this is straightforward in Python and I know how to do it.

    from PySide import QtGui, QtCore
    
    class MyProgressBar(QtGui.QProgressBar):
    """
        Progress bar in busy mode with text displayed at the center.
    """
    
        def __init__(self):
            super().__init__()
            self.setRange(0, 0)
            self.setAlignment(QtCore.Qt.AlignCenter)
            self._text = None
    
        def setText(self, text):
            self._text = text
    
        def text(self):
            return self._text
    
    app = QtGui.QApplication([])
    
    p = MyProgressBar()
    p.setText('finding resource...')
    p.show()
    
    app.exec_()
    

    gives

    enter image description here

    This is on Windows 7.

    Btw. First I thought about the brute force approach: QStackedLayout with a QLabel on top of a QProgressBar. That should also always work.