将列中心的像素图与 QTreeView 和 QAbstractItemModel 对齐

align pixmap in column's center with QTreeView and QAbstractItemModel

如何使像素图在 QTreeView 中以其列为中心对齐?我有 2 列图标向左对齐,但我希望其中一列居中,因此这需要在单个列上工作,而不是强制整个 table 对齐。

我正在使用 QTreeViewQAbstractItemModel 作为模型。在一列上,我在模型的 data() 方法中将其标记为 QtCore.Qt.DecorationRole 和 return 一个像素图,以便它沿该列显示图像。

一切正常,除了图像都左对齐,而且我无法让它们水平居中。

data() 方法中,如果角色是 QtCore.Qt.TextAlignmentRole,我尝试 returning QtCore.Qt.AlignCenter,但这似乎只影响文本(呃!)。

还有其他方法可以实现吗?如果可能的话,我对走代表路线不感兴趣。

一个可能的解决方案是覆盖委托的 initStyleOption() 方法:

from PySide2 import QtCore, QtGui, QtWidgets


class IconCenterDelegate(QtWidgets.QStyledItemDelegate):
    def initStyleOption(self, option, index):
        super(IconCenterDelegate, self).initStyleOption(option, index)
        option.decorationAlignment = (
            QtCore.Qt.AlignHCenter | QtCore.Qt.AlignCenter
        )
        option.decorationPosition = QtWidgets.QStyleOptionViewItem.Top


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = QtWidgets.QTreeView()
    model = QtGui.QStandardItemModel(w)
    w.setModel(model)
    delegate = IconCenterDelegate(w)
    w.setItemDelegateForColumn(1, delegate)
    icons = [
        "SP_TitleBarMinButton",
        "SP_TitleBarMenuButton",
        "SP_TitleBarMaxButton",
        "SP_TitleBarCloseButton",
        "SP_TitleBarNormalButton",
        "SP_TitleBarShadeButton",
        "SP_TitleBarUnshadeButton",
        "SP_TitleBarContextHelpButton",
        "SP_MessageBoxInformation",
        "SP_MessageBoxWarning",
        "SP_MessageBoxCritical",
        "SP_MessageBoxQuestion",
        "SP_DesktopIcon",
    ]
    parent = model.invisibleRootItem()
    for icon_name in icons:
        icon = QtWidgets.QApplication.style().standardIcon(
            getattr(QtWidgets.QStyle, icon_name)
        )
        its = []
        for _ in range(3):
            it = QtGui.QStandardItem()
            it.setIcon(icon)
            its.append(it)
        parent.appendRow(its)
    model.appendRow(it)
    w.resize(640, 480)
    w.expandAll()
    w.show()
    sys.exit(app.exec_())


如果你想让所有列的图标居中对齐,那么你可以覆盖视图的 viewOptions() 方法:

class TreeView(QtWidgets.QTreeView):
    def viewOptions(self):
        option = super().viewOptions()
        option.decorationAlignment = (
            QtCore.Qt.AlignHCenter | QtCore.Qt.AlignCenter
        )
        option.decorationPosition = QtWidgets.QStyleOptionViewItem.Top
        return option