выровнять растровое изображение по центру столбца с помощью QTreeView и QAbstractItemModel

Как сделать выравнивание растрового изображения по центру его столбца в QTreeView? У меня есть 2 столбца со значками, выровненными по левому краю, но я хочу, чтобы один из них располагался по центру, поэтому это должно работать с одним столбцом, а не принуждать всю таблицу к одному выравниванию.

Я использую QTreeView с QAbstractItemModel в качестве модели. В одном столбце я пометил его как QtCore.Qt.DecorationRole и вернул растровое изображение в методе модели data(), чтобы он отображал изображения вдоль этого столбца.

Все работает хорошо, за исключением того, что все изображения выравниваются по левому краю, и я не могу отцентровать их по горизонтали.

В методе data() я попытался вернуть QtCore.Qt.AlignCenter, если роль была QtCore.Qt.TextAlignmentRole, но, похоже, это влияет только на текст (да!).

Есть ли другой способ добиться этого? Я не заинтересован в том, чтобы идти путем делегатов, если это возможно.


person Green Cell    schedule 04.06.2019    source источник
comment
@eyllanesc Эй, ничего, если я оставлю тег qt? У него множество наблюдателей, и я не возражаю, если решение находится за пределами Python.   -  person Green Cell    schedule 04.06.2019
comment
Если вы считаете, что в моем издании убрано что-то важное, вы можете добавить это, поскольку вы ОП, у каждого свой критерий. С другой стороны, я отметил дубликат, потому что метод, используемый в QTableWidget, одинаков для QTreeView, поскольку он основан на методе в методе viewOptions, принадлежащем базовому классу QAbstractItemView.   -  person eyllanesc    schedule 04.06.2019
comment
В следующей ссылке приведен пример для PySide2 gist.github.com/eyllanesc/525a5f7dfd6fd51faa9fb2dd515d5bc5   -  person eyllanesc    schedule 04.06.2019
comment
Все в порядке, я не хотел наступать вам на пятки и рисковать войной редактирования (некоторые люди здесь легко ошибаются!) Дублирующий вопрос действительно исправляет выравнивание, но для ВСЕЙ таблицы, а не для столбца. В моем случае я не могу использовать это решение, так как оно портит значки в других столбцах.   -  person Green Cell    schedule 04.06.2019
comment
1) У меня уже много времени здесь, поэтому я уже знаю эти войны за то, что это для меня: если ОП отклонит мое редактирование, то я буду следовать своему пути, и если мое редактирование было правильным, у другого пользователя будет возможность сделать снова редактирование. 2) То, что вы указываете, не очень понятно, возможно, поможет размещение изображения ошибки, которая приводит к решению дублирующего вопроса, который я указал, возможно, то, что вы указали в своей публикации, может быть интерпретировано по-разному, поэтому, возможно, я отмечаю это как дубликат, вписывающийся в одну из интерпретаций.   -  person eyllanesc    schedule 04.06.2019
comment
Не беспокойтесь, я понимаю ваши рассуждения. Ну, у меня есть 2 столбца, в которых используются значки, которые по умолчанию выравниваются по левому краю. Я хочу, чтобы 2-й столбец выравнивался по центру, а 1-й оставался слева. Это решение заставляет оба значка располагаться по центру, поскольку это операция для всей таблицы. Если это все еще не ясно, я могу опубликовать скриншот.   -  person Green Cell    schedule 04.06.2019
comment
Ваш комментарий ясен, я рекомендую разместить в вашей публикации, что они хотят изменить только выравнивание значка одного столбца, в вашем вопросе не ясно, что.   -  person eyllanesc    schedule 04.06.2019
comment
Именно, чтобы изменить выравнивание только одного столбца. Извините, я могу отредактировать свой вопрос, чтобы включить это. Я просто не думал, что это проблема, когда я писал!   -  person Green Cell    schedule 04.06.2019


Ответы (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
person eyllanesc    schedule 04.06.2019
comment
Потрясающий! Только что проверил с QAbstractItemModel, все работает! Мне пришлось включить мой QTreeView в качестве родителя в конструктор делегата, иначе он вылетит, но, вероятно, это потому, что я не использую QStandardItemModel и QStandardItem - person Green Cell; 04.06.2019