0

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.

6
  • Do you mean that your code crashes specifically at the line of 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 implementing data twice. Commented Jan 5, 2022 at 13:47
  • I added a minimal example. There occurs no error, it just doesn't happen anything Commented Jan 5, 2022 at 14:21
  • When I connect the update_cells function to the QTableView it 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() Commented Jan 5, 2022 at 14:23
  • If you get no error, why in your question you claim that when you try to connect to dataChanged "there is no attribute connect"? In any case, connecting update_cells for 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. Commented Jan 5, 2022 at 16:24
  • wrong choice of words. The dataChanged just not offer the attachment connect. 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 Commented Jan 5, 2022 at 16:49

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.