PDA

View Full Version : QAbstractProxyModel->QSqlTableModel->QTableView problem



zword
11th March 2015, 14:50
Hi!

I need a ProxyModel between QTableView and QSqlTableModel.

I implemented QAbstractProxyModel's pure virtual methods like this
(this proxy actually does nothing new, just redirects everything to QSqlTableModel)



int
ProxyModel::columnCount(const QModelIndex & parent) const
{
return sourceModel()->columnCount(mapToSource(parent));
}

int
ProxyModel::rowCount(const QModelIndex & parent) const
{
return sourceModel()->rowCount(mapToSource(parent));
}

bool
ProxyModel::setData(const QModelIndex &index, const QVariant &value,
int role)
{
qDebug()<<"Column,row:"<<index.column()<<index.row()<<"Role:"<<role;

return sourceModel()->setData(index, value, role);
}

Qt::ItemFlags
ProxyModel::flags(const QModelIndex &index) const
{
qDebug()<<"flags: col,row"<<index.column()<<index.row();

return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
}

QVariant
ProxyModel::data(const QModelIndex & index, int role) const
{
return sourceModel()->data(index, role);
}

QVariant
ProxyModel::headerData(int section, Qt::Orientation orientation,
int role) const
{
return sourceModel()->headerData(section, orientation, role);
}

QModelIndex
ProxyModel::mapToSource(const QModelIndex & proxyIndex) const
{
qDebug()<<"MapToSource: col,row:"<<proxyIndex.column()<<proxyIndex.row();
if( !proxyIndex.isValid() )
return QModelIndex();

if ( proxyIndex.isValid() )
qDebug()<<"MapToSource: col,row:"<<proxyIndex.column()<<proxyIndex.row();

return sourceModel()->index(proxyIndex.row(), proxyIndex.column());
}

QModelIndex
ProxyModel::mapFromSource(const QModelIndex & sourceIndex) const
{
qDebug()<<"mapFromSource: col,row:"<<sourceIndex.column()<<sourceIndex.row();

return index(sourceIndex.row(), sourceIndex.column());
}

QModelIndex
ProxyModel::index(int row, int column, const QModelIndex & parent) const
{
if ( !parent.isValid() ) {
QModelIndex idx = createIndex(row, column);
qDebug()<<"index: col,row:"<<column<<row<<", idx: col,row:"<<idx.column()<<idx.row()<<idx.internalPointer();
return idx;
}

return QModelIndex() ;
}

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



and proxy installation


QSqlTableModel *model = new QSqlTableModel(this);
model->setTable("table1");

ProxyModel *proxyModel = new ProxyModel(this);
proxyModel->setSourceModel(model);

tableView->setModel(proxyModel);
model->select()


But the table is blank.

When i changed QSqlTableModel with QSqlQueryModel everything's fine - table display database's values.

And if use QSqlTableModel with QSortFilterProxyModel proxy (insted of my ProxyModel) everything is also ok.

I cannot figure out what's wrong with my proxy.
Help!

anda_skoa
11th March 2015, 15:17
You don't map the index used in data() and setData().

Btw, just in case your final proxy does not change the structure of the source model, it might be more convenient to derive from QIdentityProxyModel.

Cheers,
_

zword
11th March 2015, 15:52
You don't map the index used in data() and setData().
Still blank.

As i said

When i changed QSqlTableModel with QSqlQueryModel everything's fine - table display database's values.
So my proxy is ok with QSqlQueryModel

And, actually data() function is not called at all (and flags() also not called)
(but with QSqlQueryModel they are called)

Added after 8 minutes:


Btw, just in case your final proxy does not change the structure of the source model, it might be more convenient to derive from QIdentityProxyModel.
i'll give it a try, thank you.

But still whats wrong with my proxy and QSqlTableModel?

anda_skoa
11th March 2015, 22:04
So my proxy is ok with QSqlQueryModel

The query model might not check the index the same way the other model does.
E.g. some model's do not check if the passed index is actually one of theirs, such a model might work even getting an index of a proxy.
Other models do check the index because they rely on internal data being present in the index.



And, actually data() function is not called at all (and flags() also not called)

Well, is rowCount() called? What does it return?.

Cheers,
_

zword
13th March 2015, 09:58
Well, is rowCount() called? What does it return?.


Yes, it is called and it returns right number or rows.

anda_skoa
13th March 2015, 15:11
And I assume columnCount() works as well?
So the table view does show the correct dimensions but does not have any content?

Cheers,
_