PDA

View Full Version : Problems with QSortFilterProxyModel



Nefastious
31st October 2009, 16:53
Hi there guys,

I have a bit of a problem here I have a tiny problem here. I have a database connected to a QSqlTableModel, which in turn is connected to a QSortFilterProxyModel which in turn is connected to a QTableView. I also have the following code for deleting records:


void mainwindow::deletedialog() {
QMessageBox::StandardButton button;
button = QMessageBox::question(this, tr("Delete Record"),
QString (tr("Are you sure you wish to delete this record?")),
QMessageBox::Yes | QMessageBox::No);

if (button == QMessageBox::Yes) {
//Declaring an item selection which we will use to see which row the user has selected
QItemSelection selection = ui->View->selectionModel()->selection();
QList<int> rows;
foreach ( const QModelIndex & index, selection.indexes() ) {
rows.append( index.row() );
}

qSort( rows );

int prev = -1;
for( int i = rows.count() - 1; i >= 0; i -= 1 ) {
int current = rows[i];
if( current != prev ) {
model->removeRows( current, 1 );
prev = current;
}
}
}


else {
QMessageBox::information(this, tr("Delete Record"), tr("Please select the record you wish to delete"));
}
}

This code works fine unless we filter the contents of the table. If we have say 600 rows i the table, and we filter everything until we obtain 1 single record, then the code above may not delete the correct record. How can I make the above code work with QSortFilterProxyModel?

Any sample code would be greatly appreciated.

Thanks in advance,

Nefastious ;)

Lykurg
31st October 2009, 17:09
Use QSortFilterProxyModel::mapToSource() to get the right index of you original model.

Nefastious
31st October 2009, 17:25
How exactly should I do that?

like this?


...
proxyModel->mapToSource();
model->removeRows( current, 1 );
...

squidge
31st October 2009, 17:30
originalindex = proxyModel->mapToSource(proxyindex);

where both originalindex and proxyindex are of type QModelIndex

Lykurg
31st October 2009, 17:39
How exactly should I do that?

like this?


...
proxyModel->mapToSource();
model->removeRows( current, 1 );
...


Before you just guess how to do, just follow the link and read:

QModelIndex QSortFilterProxyModel::mapToSource ( const QModelIndex & proxyIndex ) const

so in your case:

foreach ( const QModelIndex & index, selection.indexes() ) {
rows.append( ui->View->model()->mapToSource(index).row() );
}

Nefastious
31st October 2009, 17:43
I'm sorry I'm going to ask this I'll probably make you all very angry at me for being such a rookie... but the following code:


index = proxyModel->mapToSource(proxyModel->index());

just doesn't work. I get an error(/Users/k12yp70n/MedCare/MedAdmin/mainw.cpp:229: error: no matching function for call to 'QSortFilterProxyModel::index()'). I don't know what I am doing wrong. Please correct me but, find a solution having in mind the code I initially posted.

Thank you... and sorry for being such a newbie...

Lykurg
31st October 2009, 18:01
What do you expect to get by "proxyModel->index()"? the selected indices you get by the selection model how you have written in your example code. And by the way: Have you written it by yourself or just copy and pasted id? Have you tried my suggestion with your code? (supposing you have set the proxy model...)

Nefastious
31st October 2009, 18:21
terribly sorry sir... i didn't read your post...

Now that I have tried the code:


rows.append( ui->View->model()->mapToSource(index).row() );

my compiler tells me that model has no member named mapToSource...

Again what am I doing wrong?

And once again please accept my apologies for having failed to read your post, and, I must sincerely thank you for all of your wisdom, knowledge, support and patience.

squidge
31st October 2009, 18:42
Doesn't model() return a QAbstractItemModel, whereas you want a QAbstractProxyModel to get mapToSource? QAbstractProxyModel inherits from QAbstractItemModel, so...



QAbstractProxyModel *q = dynamic_cast<QAbstractProxyModel*>(ui->View->model());
if (q) q->mapToSource(...)
else q isn't a valid pointer to a QAbstractProxyModel


Just a guess...

Lykurg
31st October 2009, 18:44
my bad. You must cast ui->View->model() to QAbstractItemModel or it your be easier if you would store a pointer to the sort model as a member variable, e.g. m_sortModel.

EDIT: I'm too late, and yes, fatjuicymole, you are right.

Lykurg
31st October 2009, 18:51
QAbstractProxyModel *q = dynamic_cast<QAbstractProxyModel*>(ui->View->model());


Since the model includes QObject it is better to use qobject_cast since
The qobject_cast() function behaves similarly to the standard C++ dynamic_cast(), with the advantages that it doesn't require RTTI support and it works across dynamic library boundaries.
But in that case I would use static_cast.