I use QTableView to display a QAbstractTableModel. I edited the QAbstractTableModel so that I can edit the cells, when displayed.
The editing in the window works perfectly, but I want to connect the data change to trigger a function, that takes the new data from the QAbstractTableModel and updates a bar chart.
An example code for the table (without the bar chart) looks like this:
import pandas as pd
import sys
from PyQt5.QtWidgets import QApplication, QTableView, QMainWindow
from PyQt5.QtCore import Qt, QAbstractTableModel
class TableModel(QAbstractTableModel):
def __init__(self, data):
super().__init__()
self._data = data
def data(self, index, role):
if role == Qt.DisplayRole:
# See below for the nested-list data structure.
# .row() indexes into the outer list,
# .column() indexes into the sub-list
return self._data.iloc[index.row(), index.column()]
def rowCount(self, index):
# The length of the outer list.
return self._data.shape[0]
def columnCount(self, index):
# The following takes the first sub-list, and returns
# the length (only works if all rows are an equal length)
return self._data.shape[1]
def data(self, index, role=Qt.DisplayRole):
if index.isValid():
if role == Qt.DisplayRole or role == Qt.EditRole:
value = self._data.iloc[index.row(), index.column()]
return str(value)
def setData(self, index, value, role):
if role == Qt.EditRole:
self._data.iloc[index.row(), index.column()] = value
return True
return False
def headerData(self, col, orientation, role):
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
return self._data.columns[col]
def flags(self, index):
return Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.table = QTableView()
data = pd.DataFrame([[1, 9, 2], [1, 0, -1], [3, 5, 2], [3, 3, 2], [5, 8, 9],], columns=["A", "B", "C"])
self.model = TableModel(data)
self.table.setModel(self.model)
self.setCentralWidget(self.table)
self.model.dataChanged.connect(self.update_cells)
def update_cells(self):
data = []
for row in range(self.model.rowCount(self)):
data.append([])
for column in range(self.model.columnCount(self)):
index = self.model.index(row, column)
# We suppose data are strings
data[row].append(str(self.model.data(index)))
data = pd.DataFrame(data, columns=["A", "B", "C"])
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
No error occurs, just nothing happens.
self.model.dataChanged.connect(self.update_cells)with an AttributeError? Please provide a minimal reproducible example that also includes that line. Also note that you're implementingdatatwice.update_cellsfunction to theQTableViewit works. But I executes the function on every click I make in the table:self.table.selectionModel().currentChanged.connect(self.update_cells)self.selectionModel = self.table.selectionModel()dataChanged"there is no attributeconnect"? In any case, connectingupdate_cellsfor the selection change doesn't make a lot of sense, since selection changes do not cause any data change. It's also not really clear what you are trying to achieve in that function anyway, especially since the return value of functions connected to a signal is always ignored.dataChangedjust not offer the attachmentconnect. I want to update a bar chart based on the model data. I just put the return statement at the end without trying to do anything with it