I tried to implement a ProgressBar delegate for a tableview and stumbled accross this example:
How to include a column of progress bars within a QTableView?
The example for the tableview/PyQt5 works perfectly well with PyQt5.
But trying it with PySide6 produces one malfunctional progressbar in the first row, and gray boxes in all the other rows. PyQt6 does not work at all, even after adding fully qualified names.
Here is the code:
gui = "PySide6"
#gui = "PyQt5"
#gui = "PyQt6"
if gui =="PyQt5":
from PyQt5.QtWidgets import QStyle, QStyledItemDelegate, QStyleOptionProgressBar,\
QApplication, QTableView
from PyQt5.QtGui import QStandardItem, QStandardItemModel
from PyQt5.QtCore import Qt
if gui == "PySide6":
from PySide6.QtWidgets import QStyle, QStyledItemDelegate, QStyleOptionProgressBar,\
QApplication, QTableView
from PySide6.QtGui import QStandardItem, QStandardItemModel
from PySide6.QtCore import Qt
if gui == "PyQt6":
from PyQt6.QtWidgets import QStyle, QStyledItemDelegate, QStyleOptionProgressBar,\
QApplication, QTableView
from PyQt6.QtGui import QStandardItem, QStandardItemModel
from PyQt6.QtCore import Qt
data = [("1", "abc", 10), ("2", "def", 60),
("3", "ghi", 20), ("4", "jkl", 80),
("5", "mno", 100)]
class ProgressDelegate(QStyledItemDelegate):
def paint(self, painter, option, index):
progress = index.data(Qt.ItemDataRole.UserRole+1000)
opt = QStyleOptionProgressBar()
opt.rect = option.rect
opt.minimum = 0
opt.maximum = 100
opt.progress = progress
opt.text = f"{progress}%"
opt.textVisible = True
QApplication.style().drawControl(QStyle.CE_ProgressBar, opt, painter)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
w = QTableView()
delegate = ProgressDelegate(w)
w.setItemDelegateForColumn(2, delegate)
model = QStandardItemModel(0, 3)
model.setHorizontalHeaderLabels(["ID", "Name", "Progress"])
for _id, _name, _progress in data:
it_id = QStandardItem(_id)
it_name = QStandardItem(_name)
it_progress = QStandardItem()
it_progress.setData(_progress, Qt.ItemDataRole.UserRole+1000)
model.appendRow([it_id, it_name, it_progress])
w.setModel(model)
w.show()
app.exec()
Anyone has a solution to this?
In Qt6 you have to indicate the orientation of the progressbar using the State_Horizontal
flag in the state
attribute, in Qt5 the orientation property was used and by default it was horizontal:
class ProgressDelegate(QStyledItemDelegate):
def paint(self, painter, option, index):
progress = index.data(Qt.ItemDataRole.UserRole + 1000)
opt = QStyleOptionProgressBar()
opt.rect = option.rect
opt.minimum = 0
opt.maximum = 100
opt.progress = progress
opt.text = f"{progress}%"
opt.textVisible = True
opt.state |= QStyle.StateFlag.State_Horizontal # <--
style = (
option.widget.style() if option.widget is not None else QApplication.style()
)
style.drawControl(
QStyle.ControlElement.CE_ProgressBar, opt, painter, option.widget
)