Модель привязки к Qt TableView

Я очень новичок в программировании Qt. Я хочу отображать данные с Qt TableView, которые я получаю из файла XML.

Я не могу найти полезный учебник о том, как создать пользовательскую модель, а затем привязать ее к TableView.

Пожалуйста, помогите, или если у кого-нибудь есть хорошие примеры, пожалуйста, поделитесь.

благодаря

Ответ 1

Модельный подход в Qt довольно универсален. Все модели наследуются от QAbstractItemModel. С помощью этого класса вы можете создавать довольно сложные макеты данных (списки, деревья, таблицы и т.д.), Но усилия для реализации тоже довольно высоки.

QStandardItemModel к использованию классом будет QStandardItemModel. Вы можете легко создать модель таблицы и добавить элементы, которые являются экземплярами QStandardItem. Вы можете использовать следующий код для начала работы:

#include <QtGui>

QStandardItemModel* createModel(QObject* parent)
{
    const int numRows = 10;
    const int numColumns = 10;

    QStandardItemModel* model = new QStandardItemModel(numRows, numColumns);
    for (int row = 0; row < numRows; ++row)
    {
        for (int column = 0; column < numColumns; ++column)
        {
            QString text = QString('A' + row) + QString::number(column + 1);
            QStandardItem* item = new QStandardItem(text);
            model->setItem(row, column, item);
        }
     }

    return model;
}

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QMainWindow window;
    QTableView* view = new QTableView;
    view->setModel(createModel(view));
    window.setCentralWidget(view);
    window.show();

    return app.exec();
}

Понимаете, он очень прост в использовании. Однако недостатком является то, что вам необходимо предоставить данные через QStandardItem, которые могут быть пустой тратой памяти. Например, предположим, что у вас есть несколько 100 МБ данных, которые вы хотите отобразить в представлении. Поскольку у вас уже есть данные, хранящиеся где-то, было бы предпочтительнее просто адаптировать их таким образом, чтобы их можно было использовать в представлении вместо создания QStandardItem для каждой ячейки.

Именно здесь вступает игра QAbstractTableModel. В следующем примере создается матрица с 250 000 записей. Вместо создания одного QStandardItem для каждого элемента матрицы мы подклассом QAbstractTableModel и реализуем три чистых виртуальных метода numRows(), numColumns() и data(), которые возвращают количество строк, столбцов и отображаемых данных.

#include <QtGui>

class MatrixModel : public QAbstractTableModel
{
public:
    MatrixModel(int numRows, int numColumns, double* data)
        : m_numRows(numRows),
          m_numColumns(numColumns),
          m_data(data)
    {
    }

    int rowCount(const QModelIndex& parent = QModelIndex()) const
    {
        return m_numRows;
    }

    int columnCount(const QModelIndex& parent = QModelIndex()) const
    {
        return m_numColumns;
    }

    QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const
    {
        if (!index.isValid() || role != Qt::DisplayRole)
            return QVariant();

        // Return the data to which index points.
        return m_data[index.row() * m_numColumns + index.column()];
    }

private:
    int m_numRows;
    int m_numColumns;
    double* m_data;
};


int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    // Create a matrix.
    const int numRows = 500;
    const int numColumns = 500;
    double matrix[numRows][numColumns];
    for (int i = 0; i < numRows; ++i)
        for (int j = 0; j < numColumns; ++j)
            matrix[i][j] = i + j;

    // Create a model which adapts the data (the matrix) to the view.
    MatrixModel model(numRows, numColumns, (double*)matrix);

    QMainWindow window;
    QTableView* view = new QTableView;
    view->setModel(&model);
    window.setCentralWidget(view);
    window.show();

    return app.exec();
}

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

Ответ 3

Вам нужна пользовательская модель, потому что вы хотите, чтобы она могла активно читать и обновлять данные из постоянно меняющегося источника XML?

Если нет, вы можете просто использовать любой обычный учебник QTableView и QStandardItemModel. Разберите XML файл самостоятельно и создайте объекты QStandardItem, добавив их в свою модель.

Пользовательская модель - это способ интегрирования чтения XML файла непосредственно в саму модель, в отличие от подхода, основанного на Item, где вы заполняете его извне.