Как реализовать многократную перезапись методов класса - PullRequest
1 голос
/ 25 февраля 2020

В моем следующем примере я хочу установить alignmet для первого и второго столбцов таблицы в двух разных классах. Но это не работает, как я хочу. В моем примере это только выравнивание первого набора столбцов.

Причина, по которой я хочу это сделать, заключается в том, что я хочу сделать некоторые базовые настройки в классе base-widget-class, а затем, если необходимо, Я хочу сделать дополнительные настройки в подклассе виджета.

import sys
from PyQt5.QtGui import QStandardItemModel
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QTableView, QApplication, QWidget, QVBoxLayout


class MyWidget(QWidget):

    def __init__(self, parent=None):
        super(MyWidget, self).__init__(parent)

        model = FirstModel(4, 2)
        model.setData(model.index(0, 0), "a", Qt.EditRole)
        model.setData(model.index(0, 1), 2, Qt.EditRole)
        model.setData(model.index(1, 0), "b", Qt.EditRole)
        model.setData(model.index(1, 1), 4, Qt.EditRole)
        model.setData(model.index(2, 0), "c", Qt.EditRole)
        model.setData(model.index(2, 1), 6, Qt.EditRole)
        model.setData(model.index(3, 0), "d", Qt.EditRole)
        model.setData(model.index(3, 1), 8, Qt.EditRole)

        tableview = QTableView()
        tableview.setModel(model)

        layout = QVBoxLayout()
        layout.addWidget(tableview)
        self.setLayout(layout)


class SecondModel(QStandardItemModel):

    def data(self, index, role=Qt.DisplayRole):
        super().data(index, role)

        # set Alignment for column 1
        if role == Qt.TextAlignmentRole:
            if index.column() == 1:
                return Qt.AlignHCenter | Qt.AlignVCenter

        return QStandardItemModel.data(self, index, role)


class FirstModel(SecondModel):

    def data(self, index, role=Qt.DisplayRole):
        super().data(index, role)

        # set Alignment for column 0
        if role == Qt.TextAlignmentRole:
            if index.column() == 0:
                return Qt.AlignHCenter | Qt.AlignVCenter

        return QStandardItemModel.data(self, index, role)


if __name__ == '__main__':

    app = QApplication(sys.argv)
    table_view = MyWidget()
    table_view.show()

    sys.exit(app.exec_())

1 Ответ

1 голос
/ 25 февраля 2020

В этом ответе я начну объяснять решение и, таким образом, пойму ошибку OP.

Решение:

Перед переопределением метода необходимо понять, что делает этот метод. Метод data() предназначен для возврата информации, связанной с ролью и QModelIndex.

Учитывая вышеизложенное в SecondModel, вы должны вернуть Qt.AlignHCenter | Qt.AlignVCenter, когда роль равна Qt.TextAlignmentRole, а столбец равен "1", в других случаях вы хотите вести себя как родитель (QStandardItemModel), тогда вы должны использовать super():

class SecondModel(QStandardItemModel):
    def data(self, index, role=Qt.DisplayRole):
        if role == Qt.TextAlignmentRole:
            if index.column() == 1:
                return Qt.AlignHCenter | Qt.AlignVCenter
        return super().data(index, role)

То же самое должно быть сделано с FirstModel:

class FirstModel(SecondModel):
    def data(self, index, role=Qt.DisplayRole):
        if role == Qt.TextAlignmentRole:
            if index.column() == 0:
                return Qt.AlignHCenter | Qt.AlignVCenter
        return super().data(index, role)

Объяснение ошибки OP:

class SecondModel(QStandardItemModel):
    def data(self, index, role=Qt.DisplayRole):
        super().data(index, role)
        # set Alignment for column 1
        if role == Qt.TextAlignmentRole:
            if index.column() == 1:
                return Qt.AlignHCenter | Qt.AlignVCenter
        return QStandardItemModel.data(self, index, role)

В этом коде он эквивалентен моему по функциональности, но содержит ненужный код, поскольку super().data(index, role) только возвращает что-то, но OP не использует результат. Также в этом случае super().data(index, role) совпадает с QStandardItemModel.data(self, index, role).

class FirstModel(SecondModel):
    def data(self, index, role=Qt.DisplayRole):
        super().data(index, role)
        # set Alignment for column 0
        if role == Qt.TextAlignmentRole:
            if index.column() == 0:
                return Qt.AlignHCenter | Qt.AlignVCenter
        return QStandardItemModel.data(self, index, role)

В этом случае super().data(index, role) не равно QStandardItemModel.data(self, index, role), поскольку родительский элемент FirstModel не QStandardItemModel, а SecondModel. Поэтому, не вызывая метод SecondModel, вы удаляете унаследованное поведение SecondModel.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...