Как установить данные внутри QAbstractTableModel

Мне нужно реализовать таблицу с Qt.

Я верю, что буду подавать иск в QAbstractTableModel, используя QTableView, используя эту модель.

Я понимаю, что мне нужно будет редактировать функции rowCount(), columnCount() и data() модели.

Однако я не понимаю, как точно установить данные внутри модели, чтобы функция data() могла ее восстановить..

Предоставлена ​​ли функция setData() для этой цели? Я видел, что в качестве параметра, который мне не нужен, требуется EditRole, поскольку я не хочу, чтобы моя таблица была доступна для редактирования.

Итак, как мне "установить" данные внутри модели или получить данные для модели, используя функцию data()?

Также как называется функция data(), то есть кто ее называет, и где ее нужно будет вызывать?

Пожалуйста, помогите мне с этим.

Спасибо.

Ответ 1

Как фактические данные хранятся в памяти, генерируются или запрашиваются из хранилища данных, полностью зависят от вас. Если это статические данные, вы можете использовать классы контейнеров Qt или настраиваемые структуры данных.

Вам нужно только переопределить метод setData() для редактируемых моделей.

Существует 4 метода, которые необходимо реализовать в не редактируемом подклассе QAbstractTableModel:

  • int rowCount()
  • int columnCount()
  • QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole )
  • QVariant data(const QModelIndex & index, int role = Qt::DisplayRole)

Эти методы вызывают из представления, обычно экземпляр QTableView. Первые два метода должны возвращать размеры таблицы. Например, если rowCount() возвращает 10 и columnCount() возвращает 4, представление будет ссылаться на метод data() 40 раз (один раз для каждой ячейки), запрашивающий фактические данные в ваших внутренних структурах данных модели.

В качестве примера предположим, что вы внедрили пользовательский слот retrieveDataFromMarsCuriosity() в своей модели. Этот слот заполняет структуру данных и подключается к экземпляру QPushButton, поэтому вы получаете свежие данные, нажимая кнопку. Теперь вам нужно сообщить об этом, когда данные будут изменены, чтобы они могли корректно обновляться. Поэтому вам нужно испустить beginRemoveRows(), endRemoveRows(), beginInsertRows(), endInsertRows() и его столбцы.

Документация Qt содержит все, что вам нужно знать об этом.

Ответ 2

Вам не нужно использовать setData(...). Вместо этого вам нужно создать подкласс QAbstractTableModel таким образом, чтобы его методы rowCount(), columnCount(), data(index) и потенциально headerData(section, horizontalOrVertical) возвращали данные, которые вы хотите отобразить. Вот пример, основанный на PyQt5:

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

headers = ["Scientist name", "Birthdate", "Contribution"]
rows =    [("Newton", "1643-01-04", "Classical mechanics"),
           ("Einstein", "1879-03-14", "Relativity"),
           ("Darwin", "1809-02-12", "Evolution")]

class TableModel(QAbstractTableModel):
    def rowCount(self, parent):
        # How many rows are there?
        return len(rows)
    def columnCount(self, parent):
        # How many columns?
        return len(headers)
    def data(self, index, role):
        if role != Qt.DisplayRole:
            return QVariant()
        # What the value of the cell at the given index?
        return rows[index.row()][index.column()]
    def headerData(self, section, orientation, role:
        if role != Qt.DisplayRole or orientation != Qt.Horizontal:
            return QVariant()
        # What the header for the given column?
        return headers[section]

app = QApplication([])
model = TableModel()
view = QTableView()
view.setModel(model)
view.show()
app.exec_()

Он взят из этого репозитория GitHub и отображает следующую таблицу:

QAbstractTableModel example