Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding model to Qt TableView

Tags:

c++

qt

qtgui

Im very new in Qt programming i want to display data with Qt TableView which im getting from XML file.

I Cannot find any useful tutorial about how to create custom model and then bind it to TableView.

Please provide some help or if anybody have some good examples please share.

Thanks

like image 581
user525717 Avatar asked Aug 10 '12 17:08

user525717


1 Answers

The model-view approach in Qt is quite versatile. All models inherit from QAbstractItemModel. With this class you can create quite complex data layouts (lists, trees, tables etc.) but the effort for the implementation is in comparison quite high, too.

A ready to use class would be QStandardItemModel. You can easily create a table model and add the items, which are instances of QStandardItem. You can use the following code to get started:

#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();
}

You see, it is really easy to use. However, a drawback is that you have to supply the data via a QStandardItem, which might be a waste of memory. For example, assume you have several 100MB of data, which you would like to display in a view. As you already have the data stored somewhere, it would be preferable to just adapt it such that it can be used in the view instead of creating a QStandardItem for every cell.

This is where QAbstractTableModel comes into play. The following example creates a matrix with 250.000 entries. Instead of creating one QStandardItem for every matrix element, we sub-class QAbstractTableModel and implement the three pure virtual methods numRows(), numColumns() and data(), which return the number of rows, columns and the data to display.

#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();
}

As you can see, the model does not duplicate any data but just serves as an adapter. If you need even more flexibility, you can go to QAbstractItemModel and event implement the creation of the model indexes, which Qt uses to specify which model data to read or write.

like image 154
Mehrwolf Avatar answered Nov 01 '22 00:11

Mehrwolf