Customized MVC Models

The MVC nature of Qt allows us to program our own custom models to fit our needs, but there are some common usecases for models which are already used and developed as open source projects.
The libQXt provides a nice CSV model that reads a CSV file with customizable params. Here's the usage example:

#include <QtGui>
#include <QxtCsvModel>

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

    QTableView v;

    QFile csv(":/cities.csv");
    csv.open(QIODevice::ReadOnly);

    // The QxtCsvModel provides a flexible model for working with
    // csv files.
    // It takes a QIODevice, a parent,
    // a header (whether the first line of the file is the header data),
    // and a separator character
    QxtCsvModel *model = new QxtCsvModel( &csv , &v, true, ';' );

    // it's safe to close the file after creating the model
    csv.close();

    v.setModel(model);
    v.show();

    return a.exec();
}

One more example for a customized model, using the Twitter latest tweets XML as a backend. Note the use of DOM classes to parse the data.

#ifndef TWITTERMODEL_H
#define TWITTERMODEL_H

#include <QAbstractItemModel>
#include <QStringList>

class QNetworkAccessManager;
class QNetworkReply;

class TwitterModel : public QAbstractListModel
{
    Q_OBJECT
public:
    explicit TwitterModel(QObject *parent = 0);

protected:
    virtual int rowCount(const QModelIndex &parent) const;
    virtual QVariant data(const QModelIndex &index, int role) const;

public slots:
    void refresh();
    void refresh(QNetworkReply *);

private:
    QNetworkAccessManager *iNet;
    QStringList iStatusTexts;

};

#endif // TWITTERMODEL_H

#include "twittermodel.h"
#include <QNetworkAccessManager>
#include <QDomDocument>
#include <QXmlInputSource>
#include <QNetworkReply>
#include <QDomNodeList>
#include <QVariant>

#include <QDebug>


TwitterModel::TwitterModel(QObject *parent) :
    QAbstractListModel(parent)
{
    iNet = new QNetworkAccessManager(this);
}

void TwitterModel::refresh()
{
    iNet->get(QNetworkRequest(QUrl("http://twitter.com/statuses/public_timeline.xml")));

    qDebug() << "sending get";
    QObject::connect(iNet, SIGNAL(finished(QNetworkReply*)),
                     this, SLOT(refresh(QNetworkReply*)));
}

void TwitterModel::refresh(QNetworkReply *reply)
{
    qDebug() << "got: " << reply->url().toString();

    QDomDocument doc;
    doc.setContent(reply);

    QDomNodeList statusNodes = doc.elementsByTagName("status");

    beginResetModel();
    iStatusTexts.clear();
    for ( int i=0; i < statusNodes.count(); ++i )
    {
        QDomNode statusNode = statusNodes.at(i);
        QDomNodeList statusFields = statusNode.childNodes();

        QDomNode textNode = statusNode.namedItem("text").firstChild();
        qDebug() << textNode.toText().data();
        if ( textNode.isText() )
        {
            iStatusTexts << textNode.toText().data();
        }
    }
    endResetModel();
}

int TwitterModel::rowCount(const QModelIndex &parent) const
{
    return iStatusTexts.size();
}

QVariant TwitterModel::data(const QModelIndex &index, int role) const
{
    if ( role == Qt::DisplayRole )
    {
        int row = index.row();
        return iStatusTexts.at(row);
    }

    return QVariant::Invalid;
}