Search code examples
pythonqtpysideqtwidgets

progress bar delegate fills vertically instead of horizontally


I'm trying to paint a column in a QTreeWidget using a QStylesItemDelegate with a custom paint method, to give the appearance of a progress bar.

However, the progress bar is filling up from bottom to top, see attached screenshot (and also, the text is not showing!): screenshot Instead, I want it to fill up from left to right, and I believe this should have been set through the QStyleOptionProgressBar.direction?

Here is the MRE to produce my screenshot:

import sys

from PySide6 import (
    QtCore,
    QtWidgets
)


class MyDelegate(QtWidgets.QStyledItemDelegate):

    def paint(self, painter, option, index):
        progress_bar_option = QtWidgets.QStyleOptionProgressBar()
        progress_bar_option.rect = option.rect
        progress_bar_option.state = QtWidgets.QStyle.State_Enabled
        progress_bar_option.direction = QtCore.Qt.LayoutDirection.LeftToRight
        progress_bar_option.fontMetrics = QtWidgets.QApplication.fontMetrics()

        progress_bar_option.minimum = 0
        progress_bar_option.maximum = 100
        progress_bar_option.textAlignment = QtCore.Qt.AlignCenter
        progress_bar_option.textVisible = True

        progress_bar_option.progress = 66
        progress_bar_option.text = 'demo'

        QtWidgets.QApplication.style().drawControl(QtWidgets.QStyle.CE_ProgressBar,
                                                progress_bar_option,  painter)


class MyWidget(QtWidgets.QTreeWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.examplerow = QtWidgets.QTreeWidgetItem(self)

        self.setHeaderLabels(['Col 1', 'Col 2', 'Col 3'])
        self.setAlternatingRowColors(True)

        self.examplerow.setText(0, 'Content in first column')
        self.examplerow.setText(1, 'second')
        self.examplerow.setText(2, str(3))

        delegate = MyDelegate(self)

        self.setItemDelegateForColumn(2, delegate)


if __name__ == "__main__":
    app = QtWidgets.QApplication()

    widget = MyWidget()

    window = QtWidgets.QMainWindow()
    window.setCentralWidget(widget)
    window.resize(800, 600)
    window.show()

    sys.exit(app.exec_())

What is the correct way to change the direction of the progress bar?


Solution

  • The direction variable has nothing to do with the progress bar orientation, since it's common for all QStyleOption classes and it's related to the text layout direction (left to right, or right to left for languages such as Hebrew or Arabic).

    What you were looking for is the orientation variable, which has been considered obsolete since Qt 5.5 in favour of the appropriate QStyle.State flag:

    # ...
    progress_bar_option.state = QtWidgets.QStyle.State_Enabled
    progress_bar_option.state |= QtWidgets.QStyle.State_Horizontal