QTableView显示模型的实时数据

时间:2017-10-17 06:49:53

标签: qt pyqt

我想使用pandas.DataFrameQTableView内容显示为表格。我有一个子类QAbstractTableModel的视图模型。这很好。

当用户更新DataFrame内容时,我遇到问题(应用程序允许用户编写脚本,用户可以直接访问DataFrame并更新它)。我想在GUI中显示更新的值。我可以通过发出dataChanged信号来做到这一点。但是有很多方法来更新DataFrame,我想知道为什么不让GUI始终显示DataFrame的内容。

有没有切换这样做?或任何其他小部件?

我可以注册一个QTimer并每1秒发出一次dataChanged - 有没有更好的方法来做到这一点。

我认为Android中的等效模型视图类与我的想法类似。

这是一个最小的代码。在这里按下按钮更新数据模型, 但视图将继续显示缓存的值。如果我在更新后发出数据更改信号,它将显示更新的值。但我希望尽可能避免这种情况,并希望视图始终显示来自DataFrame

的数据
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QTableView
from PyQt5.QtWidgets import QVBoxLayout
from PyQt5.QtWidgets import QPushButton
from PyQt5.QtWidgets import QWidget
import pandas as pd

from PyQt5.QtCore import QAbstractTableModel
from PyQt5.QtCore import Qt


class DFTableModel(QAbstractTableModel):
    def __init__(self, df):
        super().__init__()
        self.df = df

    def rowCount(self, parent):
        return len(self.df)

    def columnCount(self, parent):
        return self.df.columns.size + 1

    def data(self, index, role):
        if index.isValid():
            if role == Qt.DisplayRole:
                if index.column() == 0:
                    return self.df.index[index.row()]
                return str(self.df.values[index.row()][index.column() - 1])

    def headerData(self, col, orientation, role):
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            if col == 0:
                return 'index'
            return self.df.columns[col - 1]
        return None

    def setData(self, index, value, role=Qt.EditRole):
        k = self.df.columns[index.column() - 1]
        self.df.set_value(index.row(), k, value)
        return True

    def flags(self, index):
        if index.column() > 0:
            return Qt.ItemIsEditable | Qt.ItemIsEnabled | Qt.ItemIsSelectable
        return Qt.ItemIsEnabled | Qt.ItemIsSelectable


def main():
    app = QApplication([])
    table_view = QTableView()
    df = pd.DataFrame({'a': [1, 2, 3]})
    model = DFTableModel(df)
    table_view.setModel(model)
    table_view.show()

    def on_button_click():
        print("Updated data")
        df.set_value(0, 'a', 33)
    button = QPushButton('Update data')
    button.clicked.connect(on_button_click)

    vbox = QVBoxLayout()
    vbox.addWidget(table_view)
    vbox.addWidget(button)

    main = QWidget()
    main.setLayout(vbox)
    main.show()
    app.exec()


if __name__ == '__main__':
    main()

0 个答案:

没有答案