PDA

View Full Version : Problem when adding a column to a QAbstractProxyModel.



ma.renaud
4th March 2014, 17:33
Hi everyone,

I'm new to the proxy system and I based my work on an old post (http://www.qtcentre.org/threads/54732-2-subclasses-of-QSortFilterProxyModel-behind-each-other?p=245012#post245012) on the subject made by Santosh Reddy. It work as expected and the dataChanged signals are emit as supposed, but I can't find a way to add content to my new column. The data function is never called so my code there don't affect the view.

Thank you for looking.

Window code:


const int ADDRESSPOSITION = 4;
const int NBADDRESSCOLUMN = 2;

setWindowTitle(QObject::tr("Liste des clients"));

m_pFenCustomer = new Fen_Customer(this);

QSqlRelationalTableModel *pModel = new QSqlRelationalTableModel(this);
pModel->setTable("customer");
pModel->setRelation(1, QSqlRelation("address", "idAddress", "address"));
pModel->setEditStrategy(QSqlTableModel::OnManualSubmit);
pModel->select();
pModel->setHeaderData(1, Qt::Horizontal, QObject::tr("Adresse"));
pModel->setHeaderData(3, Qt::Horizontal, QObject::tr("Nom du Client"));
pModel->setHeaderData(4, Qt::Horizontal, QObject::tr("Numéro de Téléphone"));
pModel->setHeaderData(5, Qt::Horizontal, QObject::tr("Poste"));
pModel->setHeaderData(6, Qt::Horizontal, QObject::tr("Courriel"));

InsertProxyModel *pProxyModel = new InsertProxyModel(ADDRESSPOSITION,NBADDRESSCOLUMN,t his);
pProxyModel->setSourceModel(pModel);

tableView->setModel(pProxyModel);

tableView->hideColumn(1);
tableView->hideColumn(2);

InsertProxyModel.h


#include <QAbstractProxyModel>
#include <QStringList>

class InsertProxyModel : public QAbstractProxyModel
{
Q_OBJECT

public:
InsertProxyModel(int insertPos, int nbCol, QObject *parent = 0);
virtual ~InsertProxyModel();

QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex & /*child*/) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
QModelIndex mapToSource(const QModelIndex &proxyIndex) const;
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
QVariant data(const QModelIndex &index, int role);
bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole);
Qt::ItemFlags flags(const QModelIndex &index) const;

private:
int m_insertPos;
int m_nbCol;

QStringList mData;

public slots:
void slotSourceModelChanged(void);
void slotDataChanged(const QModelIndex first, QModelIndex last);

};

InsertProxyModel.cpp


#include "insertProxyModel.h"

//--------------------------------------------------------------------------

InsertProxyModel::InsertProxyModel(int insertPos, int nbCol, QObject *parent) : QAbstractProxyModel(parent), mData()
{
m_insertPos = insertPos;
m_nbCol = nbCol;

connect(this, SIGNAL(sourceModelChanged()), this, SLOT(slotSourceModelChanged()));
}

//--------------------------------------------------------------------------

InsertProxyModel::~InsertProxyModel()
{
}

//--------------------------------------------------------------------------

QModelIndex InsertProxyModel::index(int row, int column, const QModelIndex & parent) const
{
QModelIndex res;
if(!parent.isValid())
{
res = createIndex(row, column);
}
return res;
}

//--------------------------------------------------------------------------

QModelIndex InsertProxyModel::parent(const QModelIndex & /*child*/) const
{
return QModelIndex();
}

//--------------------------------------------------------------------------

int InsertProxyModel::rowCount(const QModelIndex & parent) const
{
int res = 0;
if(!parent.isValid())
{
res = (sourceModel()->rowCount(QModelIndex()));
}
return res;
}

//--------------------------------------------------------------------------

int InsertProxyModel::columnCount(const QModelIndex & parent) const
{
int res = 0;
if(!parent.isValid())
{
res = sourceModel()->columnCount() + m_nbCol;
}
return res;
}

//--------------------------------------------------------------------------

QModelIndex InsertProxyModel::mapToSource(const QModelIndex & proxyIndex) const
{
QModelIndex res;
if(proxyIndex.isValid())
{
if(proxyIndex.column() >= m_insertPos && proxyIndex.column() <= (m_insertPos+m_nbCol-1))
{
res = createIndex(proxyIndex.row(), -1, (quintptr)-1);
}
else if(proxyIndex.column() < m_insertPos)
{
res = sourceModel()->index(proxyIndex.row(), proxyIndex.column());
}
else
{
res = sourceModel()->index(proxyIndex.row(), proxyIndex.column()-m_nbCol);
}
}
return res;
}

//--------------------------------------------------------------------------

QModelIndex InsertProxyModel::mapFromSource(const QModelIndex & sourceIndex) const
{
QModelIndex res;
if(!sourceIndex.isValid())
{
if((sourceIndex.row() > -1) &&
(sourceIndex.column() >= m_insertPos && sourceIndex.column() <= (m_insertPos+m_nbCol-1)) &&
(sourceIndex.internalId() == (quintptr)(sourceIndex.column())))
{
res = index(sourceIndex.row(), sourceIndex.column());
}
}
else
{
res = index(sourceIndex.row(), sourceIndex.column());
}
return res;
}

//--------------------------------------------------------------------------

QVariant InsertProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
{
QVariant res;
if(orientation == Qt::Horizontal)
{
if(section >= m_insertPos && section <= (m_insertPos+m_nbCol-1))
{
res = QString("Proxy Column");
}
else if(section < m_insertPos)
{
res = sourceModel()->headerData(section, orientation, role);
}
else
{
res = sourceModel()->headerData(section-m_nbCol, orientation, role);
}
}
else
{
res = sourceModel()->headerData(section, orientation, role);
}
return res;
}

//--------------------------------------------------------------------------

QVariant InsertProxyModel::data(const QModelIndex &index, int role)
{
QVariant res;
if(index.column() >= m_insertPos && index.column() <= (m_insertPos+m_nbCol-1))
{
if((role == Qt::DisplayRole) || (role == Qt::EditRole))
{
if(index.row() < mData.size())
{
//res = mData.at(index.row());
//I try to put the same test text in all the added column here
res = "bleh";
}
}
}
else
{
res = sourceModel()->data(mapToSource(index), role);
}
return res;
}

//--------------------------------------------------------------------------

bool InsertProxyModel::setData(const QModelIndex & index, const QVariant & value, int role)
{
bool res = false;
if(index.column() >= m_insertPos && index.column() <= (m_insertPos+m_nbCol-1))
{
if((role == Qt::DisplayRole) || (role == Qt::EditRole))
{
while((index.row() + 1) > mData.size())
{
mData.append(QString());
}
mData[index.row()] = value.toString();
return true;
}
}
else
{
res = sourceModel()->setData(mapToSource(index), value, role);
}
return res;
}

//--------------------------------------------------------------------------

Qt::ItemFlags InsertProxyModel::flags(const QModelIndex &index) const
{
Qt::ItemFlags res;
if(index.column() >= m_insertPos && index.column() <= (m_insertPos+m_nbCol-1))
{
res = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
}
else
{
res = sourceModel()->flags(mapToSource(index));
}
return res;
}

//--------------------------------------------------------------------------

void InsertProxyModel::slotSourceModelChanged(void)
{
disconnect(this, SLOT(slotDataChanged(QModelIndex,QModelIndex)));
connect(sourceModel(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(slotDataChanged(QModelIndex,QModelIndex)));
}

//--------------------------------------------------------------------------

void InsertProxyModel::slotDataChanged(const QModelIndex first, QModelIndex last)
{
emit dataChanged(mapFromSource(first), mapFromSource(last));
}

//--------------------------------------------------------------------------

ma.renaud
4th March 2014, 23:20
I finally found the solution to my problem. When you subclass QAbstractProxyModel be sure to make the data function const. :rolleyes: