QTableView 没有显示我的部分数据和 resetHeaderData 没有用 PyQt5 和 Python 触发

QTableView not showing part of my data and resetHeaderData not fired with PyQt5 and Python

这是一个简单的问题,但我无法解决!

  1. 数据源是pandas的DataFrame,布尔值,我的tableview的第二列值没有显示。为什么?
  2. 在主窗口 Class 中,我使用 [=24= 的 'setHeaderData' 函数将第二列的名称从 'T/F' 重置为 'True/False' (实际上只是为了测试) ] 继承自 'QAbstractTableModel'。但是第二列名称没有改变。为什么?非常感谢!
import sys
import typing
import pandas as pd
from PyQt5.QtWidgets import QApplication, QMainWindow, \
    QWidget, QTableView, QHBoxLayout
from PyQt5.QtCore import QAbstractTableModel, Qt


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        myTable = QTableView()
        df_data = [['strong', True], ['Pretty', False]]
        df_index = ['0', '1']
        df_column = ['Type', 'T/F']
        df = pd.DataFrame(data=df_data, index=df_index, columns=df_column)
        model = MyTableModel(df)
        model.setHeaderData(1, Qt.Horizontal, 'True/False', role=Qt.DisplayRole)
        myTable.setModel(model)
        hlayout = QHBoxLayout()
        hlayout.addWidget(myTable)
        dummy_widget = QWidget()
        dummy_widget.setLayout(hlayout)
        self.setCentralWidget(dummy_widget)


class MyTableModel(QAbstractTableModel):
    def __init__(self, data: pd.DataFrame):
        super().__init__()
        self._data = data
        self.header = self._data.columns.tolist()

    def data(self, index, role):
        if role == Qt.DisplayRole:
            value = self._data.iloc[index.row()][index.column()]
            return value

    def rowCount(self, index) -> int:
        return self._data.shape[0]

    def columnCount(self, index) -> int:
        return self._data.shape[1]

    def headerData(self, section: int, orientation: Qt.Orientation, role: int = ...) -> typing.Any:
        if role == Qt.DisplayRole and orientation == Qt.Horizontal:
            return self._data.columns[section]


app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()

您的代码中应更改的两件事:

  1. 在您的 MyTableModel.HeaderData 方法中,您使用 self._data 作为 header 值的来源,而不是 self.header。既然你已经有了 .header 列表,你应该使用它。
  2. 正如 @musicamante 所述,如果您在视图中使用抽象模型,则需要自己实现 setHeaderData

这是一段代码,您可以将其添加到您的模型中 class:

def headerData(self, section: int, orientation: Qt.Orientation, role: int = ...) -> typing.Any:
    if role == Qt.DisplayRole and orientation == Qt.Horizontal:
        return self.header[section]

def setHeaderData(self, section: int, orientation: Qt.Orientation, value: typing.Any, role: int = ...) -> bool:
    if role == Qt.DisplayRole:
        self.header[section] = value
        self.headerDataChanged.emit(orientation, section, section)
        return True
    else:
        return False

documentation 中所述,对于 setHeaderData 您应该始终发出 headerDataChanged 信号。

编辑:
对于您的问题,为什么您的 bool 数据未显示。
您需要将其转换为字符串。
所以只需将 data 方法更改为:

def data(self, index, role):
    if role == Qt.DisplayRole:
        value = str(self._data.iloc[index.row()][index.column()])
        return value