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;
}
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;
}