smallB
smallB

Reputation: 17138

Creating my own model in QT

I've created my own model class:

    #ifndef FILE_LISTING_MODEL_H
    #define FILE_LISTING_MODEL_H

    #include <QAbstractItemModel>
    #include <QStringList>

    class File_Listing_Model : public QAbstractItemModel
    {
        Q_OBJECT
    private:
        QStringList selected_files_;
    public:
        explicit File_Listing_Model(QObject *parent = 0);
        virtual int columnCount(const QModelIndex & parent = QModelIndex()) const;
        virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
        virtual QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
        virtual QModelIndex parent(const QModelIndex & index) const;
        virtual int rowCount(const QModelIndex & parent = QModelIndex()) const;
        void set_model_data(const QStringList&);
    signals:

    public slots:

    };

    #endif // FILE_LISTING_MODEL_H
    #include "File_Listing_Model.h"

    File_Listing_Model::File_Listing_Model(QObject *parent) :
        QAbstractItemModel(parent)
    {
    }

    int File_Listing_Model::columnCount(const QModelIndex & /*parent*/) const
    {
        return 1;
    }

    QVariant File_Listing_Model::data(const QModelIndex & index, int role) const
    {
        if (role == Qt::DisplayRole)
        {
            return selected_files_.at(0);//THIS IS JUST A DUMMY
        }
        else
        {
            return QVariant();
        }

    }

    QModelIndex File_Listing_Model::index(int row, int column, const QModelIndex &/* parent*/) const
    {
        return createIndex(row,column);
    }

    QModelIndex File_Listing_Model::parent(const QModelIndex & index) const
    {
        return QModelIndex();
    }

    int File_Listing_Model::rowCount(const QModelIndex & /*parent*/) const
    {
        return selected_files_.count();
    }

    void File_Listing_Model::set_model_data(const QStringList& data)
    {
        selected_files_ = data;
    }

Then I've set this model in my dialog class which looks like:

#ifndef DIALOG_H
#define DIALOG_H

#include "ui_Dialog.h"
#include "File_Listing_Model.h"
class Dialog : public QDialog, private Ui::Dialog
{
    Q_OBJECT
private:
    File_Listing_Model* model_;
private slots:
    void add_files();
public:
    explicit Dialog(QWidget *parent = 0);
};

#endif // DIALOG_H

#include "Dialog.h"
#include <QFileDialog>
Dialog::Dialog(QWidget *parent) :
    QDialog(parent),model_(new File_Listing_Model(this))
{
    setupUi(this);
    listView->setModel(model_);
}

void Dialog::add_files()
{
    QStringList tmp = QFileDialog::getOpenFileNames();

    if (!tmp.isEmpty())
    {
        model_->set_model_data(tmp);
    }
}

Unfortunately after selecting files via add files which is connected to add_files() slot nothing is displayed in listView in my dialog
dialog.
Does anyone know how to solve it?

Upvotes: 0

Views: 1840

Answers (4)

JediLlama
JediLlama

Reputation: 1173

The model needs to be informed that you've added/changed data. Starting with Qt 4.6, if you're setting your data in one hit, you could change your set_model_data() function to:

void File_Listing_Model::set_model_data(const QStringList& data)
{
    beginResetModel();
    selected_files_ = data;
    endResetModel();
}

Upvotes: 2

pnezis
pnezis

Reputation: 12331

Check the beginInsertRows function :

This function emits the rowsAboutToBeInserted() signal which connected views (or proxies) must handle before the data is inserted. Otherwise, the views may end up in an invalid state.

Similarly you have to call the endInsertRows in order to notify the view that the insertion has been completed.

So your set_model_data function should be:

void File_Listing_Model::set_model_data(const QStringList& data)
{
    beginInsertRows();
    selected_files_ = data;
    endInsertRows();
}

Upvotes: 1

gureedo
gureedo

Reputation: 315

You must inform you model about that data is modified. When you call void Dialog::add_files() model dosen't know about data changing.

Simply you can call reset() or revert() on you model. But it's not a a good practice and it's too slow.

Read about inserting and deleting items in qt manual.

Upvotes: 0

crazyjul
crazyjul

Reputation: 2539

First of all, you should use ModelTest ( http://developer.qt.nokia.com/wiki/Model_Test ). It detects most common error and validates your model is correct.

In your specific example, you forget to signal the model has been changed. The view listen to model signals and react to it.

In your set_model_data() function, try to add modelReset()

int File_Listing_Model::rowCount(const QModelIndex & /*parent*/) const
{
    int c = selected_files_.count();

    reset();

    return c;
}

Upvotes: 0

Related Questions