ProgressBarColumnDelegate 与 PySide6/PyQt6

ProgressBarColumnDelegate with PySide6/PyQt6

我试图为表视图实现 ProgressBar 委托,但无意中发现了这个例子:

tableview/PyQt5 的示例与 PyQt5 完美配合。

但是用 PySide6 尝试它会在第一行产生一个故障进度条,在所有其他行产生灰色框。 PyQt6 根本不起作用,即使在添加完全限定名称之后也是如此。

代码如下:

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()

有人对此有解决方案吗?

在 Qt6 中,您必须使用 state 属性中的 State_Horizontal 标志来指示进度条的方向,在 Qt5 中使用方向 属性,默认情况下它是水平的:

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
        )