【问题标题】:align pixmap in column's center with QTreeView and QAbstractItemModel将列中心的像素图与 QTreeView 和 QAbstractItemModel 对齐
【发布时间】:2019-06-04 06:36:27
【问题描述】:

如何在QTreeView 中将像素图对齐到其列的中心?我有 2 列图标左对齐,但我希望其中之一居中,所以这需要在单个列上工作,而不是强制整个表格对齐。

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

一切都很好,除了图像都向左对齐,而且在我的生活中,我无法将它们水平居中。

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

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

【问题讨论】:

  • @eyllanesc 嘿,如果我保留qt 标签可以吗?它有大量的观察者,我不介意解决方案是否在 python 之外。
  • 如果您认为我的版本删除了一些重要的内容,您可以添加它,因为您是 OP,每个版本都有不同的标准。另一方面,我标记了一个重复项,因为 QTableWidget 中使用的方法与 QTreeView 相同,因为它基于 viewOptions 方法中的方法,该方法属于基类 QAbstractItemView
  • 在下面的链接中有一个 PySide2 gist.github.com/eyllanesc/525a5f7dfd6fd51faa9fb2dd515d5bc5的例子
  • 没关系,我不想踩到你的脚趾并冒着编辑战争的风险(这里的一些人很容易把事情搞错!)重复的问题确实解决了对齐问题,但是对于与列相对的整个表。就我而言,我不能使用这个解决方案,因为它搞砸了其他列上的图标。
  • 1) 我在这里已经有很多时间了,所以我已经知道这些战争对我来说意味着什么:如果 OP 拒绝我的编辑,那么我将遵循我的道路,如果我的编辑是正确的另一个用户将有机会再次进行编辑。 2)你指出的不是很清楚,也许放置一个错误的图像来解决我指出的重复问题可能会有所帮助,也许你在出版物中指出的可以用不同的方式解释,所以也许我标记它是重复的,符合其中一种解释。

标签: python qt qtreeview pyside2 qabstractitemmodel


【解决方案1】:

一种可能的解决方案是覆盖委托的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

【讨论】:

  • 太棒了!刚刚用QAbstractItemModel 测试过,它可以工作!我必须将我的QTreeView 作为父级包含在委托的构造函数中,否则它会崩溃,但这可能是因为我没有使用QStandardItemModelQStandardItem
猜你喜欢
  • 2016-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-29
  • 1970-01-01
  • 1970-01-01
  • 2016-07-23
  • 2013-09-17
相关资源
最近更新 更多