PDA

View Full Version : QtAbstractModel and checkboxes



paradoxi
3rd April 2013, 16:21
Hi everybody,

I have managed to create a custom model by implementing QAbstractModel and setting my data from a vector of structures(setting the first 3 columns). But when I try and add checkboxes on the fourth column I seem unable to make these checkable or uncheckable.
The last 2 days I have been searching the internet and understand that I need a virtual method which is called setData. Even so I seem unable to get it to work as I want. (The fourth column shows the checkboxes, but I cannot change to checked / unchecked).

Any help or advice towards the correct way to do this would be highly appreciated. Other then the issue with the checkbox the Abstract model is usable in a Qtableview and visualises 3.7 million rows of genome data without a glitch and at high speed. (which impressed me).

header

#ifndef DATALISTMODEL_H
#define DATALISTMODEL_H

#include <QAbstractTableModel>
#include <QMap>
#include <vector>
#include <QFont>
#include <QCheckBox>

struct dataStructRow
{
std::string markername;
std::string samplename;
std::string geno;
};

class dataListModel : public QAbstractTableModel
{
public:
explicit dataListModel(std::vector<dataStructRow> &dataStructList, QObject *parent = 0);

int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const;
Qt::ItemFlags flags ( const QModelIndex &index ) const;
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole);

private:
dataStructRow dataMap;
std::vector<dataStructRow>& _dataStructList;
QList<QString> _headers;
QFont _font;
};

#endif


Implementation

#include <QtCore>

#include "datalistmodel.h"

dataListModel::dataListModel(std::vector<dataStructRow> &dataStructList, QObject *parent)
: QAbstractTableModel(parent), _dataStructList(dataStructList), _font(QFont("Courier", 10, QFont::Bold))
{
_headers << "Markername" << "Sample" << "genotype" << "Select";
}


int dataListModel::rowCount(const QModelIndex & /* parent */) const
{
return _dataStructList.size();
}

int dataListModel::columnCount(const QModelIndex & /* parent */) const
{
return 4;
}

QVariant dataListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid()) {
return QVariant();
} else if (role == Qt::DisplayRole) {
dataStructRow perRowdataStruct = _dataStructList[index.row()];
switch(index.column()) {
case 0:
return QString::fromStdString(perRowdataStruct.markername );
case 1:
return QString::fromStdString(perRowdataStruct.samplename );
case 2:
return QString::fromStdString(perRowdataStruct.geno);
default:
return QVariant();
}
} else if (index.column() == 3 && role == Qt::CheckStateRole) {
return Qt::ItemIsUserCheckable;
} else {
return QVariant();
}
}

QVariant dataListModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role == Qt::DisplayRole) {
if (orientation == Qt::Horizontal){
return _headers[section];
}
} else if ( role == Qt::FontRole) {
return _font;
}
return QVariant();
}

bool dataListModel::setData(const QModelIndex & index, const QVariant & value, int role)
{
if (index.isValid() && role == Qt::EditRole) {
emit dataChanged(index, index);
return true;
}
return false;
}


Qt::ItemFlags dataListModel::flags(const QModelIndex& index) const
{
Qt::ItemFlags flags = QAbstractItemModel::flags(index);
flags |= (Qt::ItemIsSelectable
|Qt::ItemIsUserCheckable
|Qt::ItemIsEnabled);
return flags;
}

Guett_31
3rd April 2013, 19:11
I think the problem is how you reimplemented data() and setData().
Take a look at that thread below. It explains how to do it with a QFileSyetemModel but it should be easily applicable to your case.
http://www.qtcentre.org/threads/27253-QFileSystemModel-with-checkboxes