PDA

View Full Version : Accessing data from a model when an item is clicked in a view



themagician
30th September 2011, 11:23
Hi. I've done all the research I can and can't solve this simple problem.

I have a model (QAbstractListModel) that loads data from a database (id, name, etc.), and puts it in a data structure QList<QHash<QString, QString> >.

Then in the model's data() method the name field is returned to the QListView.

Code for the model looks something like this (I removed some unnecessary stuff so there might be some inconsistencies):


class MovieListModel : public QAbstractListModel
{
Q_OBJECT

private:
QList<QHash<QString, QString> > lists;

public:
MovieListModel(QObject *parent = 0);
int rowCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
};

MovieListModel::MovieListModel(QObject *parent) : QAbstractListModel(parent)
{
QSqlQuery query;
query.exec("SELECT id, name FROM movie_lists ORDER BY id ASC");

while(query.next())
{
QHash<QString, QString> movieData;

movieData["id"] = query.value(0).toString();
movieData["name"] = query.value(1).toString();

lists << movieData;
}
}

int MovieListModel::rowCount(const QModelIndex &parent) const
{
return lists.size();
}

QVariant MovieListModel::data(const QModelIndex &index, int role) const
{
if(role == Qt::DisplayRole)
{
QHash<QString, QString> movieData = lists.at(index.row());

return movieData["name"];
}

return QVariant();
}

And then I set the model to a view:


MovieListModel *mdl = new MovieListModel(this);
QListView *view = new QListView(this);
view->setModel(mdl);

Then I have another widget that inherits from QAbstractScrollArea and what I want to do is when I click an item in the view, I want to access that item's QHash<QString, QString> data from the widget that inherits from QAbstractScrollArea, lets call it MovieItemArea that's populated by movie item widgets that belong to the list that was clicked. So in the MovieItemArea class I would have something like this:


MovieItemArea::loadMovieItems(const QHash<QString, QString>& movieData)
{
int listId = movieData["id"].toInt();

// SQL query to load movies for that list id...
}

I can extract the list name like this:


connect(view, SIGNAL(clicked(QModelIndex)), movieItemArea, SLOT(loadMovieItems(QModelIndex)));

When the function implementation is a little different as well:


MovieItemArea::loadMovieItems(const QModelIndex& movieData)
{
QMessageBox::information(this, tr("List name"), movieData.data().toString();
}

But I can't figure out a way to access all the data.

Also this is my first proper Qt app so if there's something to improve let me know.

Thanks.

vfernandez
30th September 2011, 19:06
You can add a method to MovieListModel that provides the QHash for the item:


QHash<QString, QString> MovieListModel::movieData(const QModelIndex& index)
{
if(index.row() < 0 || index.row() >= list.count()) {
return QHash<QString, QString>();
} else {
return list.at(index.row());
}
}

Then in loadMovieItems you can do this:


MovieItemArea::loadMovieItems(const QModelIndex& movieData)
{
QHash<QString, QString> movieData = model->movieData(movieData);
QMessageBox::information(this, tr("List name"), movieData.value("name"));
}