PyQt5 更新可编辑 QTableView 中的值 [英] PyQt5 update values in editable QTableView

查看:443
本文介绍了PyQt5 更新可编辑 QTableView 中的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个可编辑的 QTableView,其中包含一系列 x 值、它们的正方形和立方体.

有没有办法在任何值发生变化时发出信号来更新同一行中的其余单元格?

例如,如果我将 x = 2 的值更改为 x = 5,那么以某种方式知道更改已经发生并且代码必须更新其余部分行中的值.

我粘贴了我的原始代码示例,以防万一.

from PyQt5.QtCore import QAbstractTableModel, Qt类 PandasModelEditable(QAbstractTableModel):def __init__(self, data):QAbstractTableModel.__init__(self)self._data = 数据def rowCount(self, parent=None):返回 self._data.shape[0]def columnCount(self, parnet=None):返回 self._data.shape[1]定义数据(自我,索引,角色=Qt.DisplayRole):如果 index.isValid():如果角色== Qt.DisplayRole:返回 str(self._data.iloc[index.row(), index.column()])column_count = self.columnCount()对于范围内的列(0,column_count):if (index.column() == column and role == Qt.TextAlignmentRole):返回 Qt.AlignHCenter |Qt.AlignVCenter返回无def headerData(self, col,orientation, role):如果方向 == Qt.Horizo​​ntal 和角色 == Qt.DisplayRole:返回 self._data.columns[col]返回无def setData(self, index, value, role):如果不是 index.isValid():返回错误如果角色 != Qt.EditRole:返回错误行 = index.row()如果行 <0 或行 >= len(self._data.values):返回错误列 = index.column()如果列<0 或 column >= self._data.columns.size:返回错误self._data.values[行][列] = 值self.dataChanged.emit(索引,索引)返回真定义标志(自我,索引):返回 Qt.ItemIsEditable |Qt.ItemIsEnabled |Qt.ItemIsSelectable如果 __name__ == '__main__':导入系统将熊猫导入为 pd从 PyQt5.QtWidgets 导入 QApplication、QTableViewdf = pd.DataFrame({'x': range(5),'x²': [i**2 for i in range(5)],'x³': [i**3 for i in range(5)]})app = QApplication(sys.argv)模型 = PandasModelEditable(df)视图 = QTableView()视图.setModel(模型)view.resize(350, 200)视图.show()sys.exit(app.exec_())

已编辑

由于善意的回答不是 100% 有帮助,而且我用 pandas DataFrame 填充了 QtableView,所以我打开了一个

I have an editable QTableView with a range of x values, their squares and their cubes.

Is there a way that if any value is changed a signal is launched to update the rest of the cells in the same row?

For instance, if I change the value x = 2 by x = 5, then somehow to know that the change has happened and the code has to update the rest of the values in the row.

I paste in a sample of my original code in case it helps.

from PyQt5.QtCore import QAbstractTableModel, Qt


class PandasModelEditable(QAbstractTableModel):

    def __init__(self, data):
        QAbstractTableModel.__init__(self)
        self._data = data

    def rowCount(self, parent=None):
        return self._data.shape[0]

    def columnCount(self, parnet=None):
        return self._data.shape[1]

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

            column_count = self.columnCount()
            for column in range(0, column_count):
                if (index.column() == column and role == Qt.TextAlignmentRole):
                    return Qt.AlignHCenter | Qt.AlignVCenter

        return None

    def headerData(self, col, orientation, role):
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            return self._data.columns[col]
        
        return None

    def setData(self, index, value, role):
        if not index.isValid():
            return False
        
        if role != Qt.EditRole:
            return False
        
        row = index.row()
        if row < 0 or row >= len(self._data.values):
            return False
        
        column = index.column()
        if column < 0 or column >= self._data.columns.size:
            return False
        
        self._data.values[row][column] = value
        self.dataChanged.emit(index, index)
        return True
    
    def flags(self, index):
        return Qt.ItemIsEditable | Qt.ItemIsEnabled | Qt.ItemIsSelectable


if __name__ == '__main__':
    
    import sys
    import pandas as pd
    from PyQt5.QtWidgets import QApplication, QTableView

    df = pd.DataFrame({'x': range(5),
                       'x²': [i**2 for i in range(5)],
                       'x³': [i**3 for i in range(5)]
                       })

    app = QApplication(sys.argv)
    model = PandasModelEditable(df)
    view = QTableView()
    view.setModel(model)
    view.resize(350, 200)
view.show()
sys.exit(app.exec_())

EDITED

Since the kind answers are not 100 % helpful and I populate the QtableView with a pandas DataFrame, I have opened a new post with a new question.

解决方案

I noted for you the lines in which I made changes.

from PyQt5.QtCore import QAbstractTableModel, Qt


class PandasModelEditable(QAbstractTableModel):

    def __init__(self, data):
        QAbstractTableModel.__init__(self)
        self._data = data

    def rowCount(self, parent=None):
        return self._data.shape[0]

    def columnCount(self, parnet=None):
        return self._data.shape[1]

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

            column_count = self.columnCount()
            for column in range(0, column_count):
                if (index.column() == column and role == Qt.TextAlignmentRole):
                    return Qt.AlignHCenter | Qt.AlignVCenter

        return None

    def headerData(self, col, orientation, role):
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            return self._data.columns[col]
        return None

    def setData(self, index, value, role):
        if not value.isdigit():                                               # +++
            return False                                                      # +++
    
        if not index.isValid():
            return False
        
        if role != Qt.EditRole:
            return False
        
        row = index.row()
        if row < 0 or row >= len(self._data.values):
            return False
        
        column = index.column()
        if column < 0 or column >= self._data.columns.size:
            return False
        
        self._data.values[row][column] = value

        self._data.values[row][1] = int(value)**2                             # +++
        self._data.values[row][2] = int(value)**3                             # +++
        
        self.dataChanged.emit(index, index)
        return True
    
    def flags(self, index):
#        return Qt.ItemIsEditable | Qt.ItemIsEnabled | Qt.ItemIsSelectable

        fl = QAbstractTableModel.flags(self, index)                           # +++
        if index.column() == 0:                                               # +++
            fl |= Qt.ItemIsEditable | Qt.ItemIsEnabled | Qt.ItemIsSelectable  # +++
        return fl                                                             # +++              


if __name__ == '__main__':
    
    import sys
    import pandas as pd
    from PyQt5.QtWidgets import QApplication, QTableView

    df = pd.DataFrame({'x': range(5),
                       'x²': [i**2 for i in range(5)],
                       'x³': [i**3 for i in range(5)]
                       })

    app = QApplication(sys.argv)
    model = PandasModelEditable(df)
    view = QTableView()
    view.setModel(model)
    view.resize(350, 200)
    view.show()
    sys.exit(app.exec_())

这篇关于PyQt5 更新可编辑 QTableView 中的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆