简体   繁体   English

如何实现类方法的多次覆盖

[英]How to realize multiple overwriting of class methods

In my exampe below, I want to set the alignmet for the first and the second column of the tableview in two different classes.在下面的示例中,我想在两个不同的类中为 tableview 的第一列和第二列设置 alignmet。 But it does not work as I want.但它不像我想要的那样工作。 In my example is only the alignment of the first column set.在我的例子中只是第一列集的对齐方式。

The reason why I want to do this is, because I want to make some base settings in a base-widget-class and then, if needed, I want to make addition settings in a subclassed widget.我之所以要这样做,是因为我想在 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_())

In this answer I will start explaining the solution and thereby understand the OP error.在这个答案中,我将开始解释解决方案,从而理解 OP 错误。

Solution:解决方案:

Before override a method, it must be understood what that method does.在覆盖方法之前,必须了解该方法的作用。 The data() method aims to return information related to a role and a QModelIndex. data()方法旨在返回与角色和 QModelIndex 相关的信息。

Considering the above in SecondModel, you must return Qt.AlignHCenter | Qt.AlignVCenter考虑到SecondModel中的上述内容,您必须返回Qt.AlignHCenter | Qt.AlignVCenter Qt.AlignHCenter | Qt.AlignVCenter when the role is Qt.TextAlignmentRole and the column is "1", in the other cases you want to behave like the parent(QStandardItemModel) then you must use super() : 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)

The same should be done with FirstModel: 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 error explanation: 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)

In this code it is equivalent to mine in functionality but it has an unnecessary code since super().data(index, role) only returns something but the OP does not use the result.在这段代码中,它在功能上等同于我的,但它有一个不必要的代码,因为super().data(index, role)只返回一些东西,但 OP 不使用结果。 Also in this case super().data(index, role) is the same as QStandardItemModel.data(self, index, role) .同样在这种情况下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)

In this case super().data(index, role) does not equal QStandardItemModel.data(self, index, role) because the parent of FirstModel is not QStandardItemModel but SecondModel .在这种情况下super().data(index, role)不等于QStandardItemModel.data(self, index, role)因为FirstModel的父FirstModel不是QStandardItemModel而是SecondModel So by not calling the method of SecondModel you are deleting the inherited behavior of SecondModel .因此,通过不调用的方法SecondModel您要删除的继承行为SecondModel

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM