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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With