PDA

View Full Version : Blank QListView when using QSortFilterProxyModel



jiveaxe
26th March 2013, 12:16
Hi, I'm playing with QSortFilterProxyModel (never used before); so I created a sample application with a QListView whose items content is controlled by delegates. This is a piece of code without proxy:


model = new MyModel(this);

ItemDelegate *itemDelegate = new ItemDelegate(ui->listView);
ui->listView->setItemDelegate(itemDelegate);

ui->listView->setModel(model);

setModelData_1();

It works fine, but if I use MySortFilterProxyModel, like in this snippet:



model = new MyModel(this);
proxyModel = new MySortFilterProxyModel(this);

ItemDelegate *itemDelegate = new ItemDelegate(ui->listView);
ui->listView->setItemDelegate(itemDelegate);

ui->listView->setModel(proxyModel);
proxyModel->setSourceModel(model);

setModelData_1();

the view is empty.

MySortFilterProxyModel is very minimal; it contains only bool QSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const returning a true.

Where am I wrong?

Thanks for your help.

Santosh Reddy
26th March 2013, 14:35
set the source of proxy model first


proxyModel->setSourceModel(model);
ui->listView->setModel(proxyModel);

jiveaxe
26th March 2013, 14:39
set the source of proxy model first


proxyModel->setSourceModel(model);
ui->listView->setModel(proxyModel);


swapping lines does not help.

Perhaps I catched the problem; proxyModel->setSourceModel(...) must be called after feeding model with data. But now my program crashes at the following line:


void ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (!index.isValid())
return;

const MyModel *model = qobject_cast<const MyModel*>(index.model());

...
QString first = model->data(index, ItemRoles::First).toString(); // <-- debugger stops here

...
}

The debugger says that model's value is 0x0 and first's value is <not accessible>

Santosh Reddy
26th March 2013, 14:42
You should be doing this.



void ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (!index.isValid())
return;

const MyModel *model = qobject_cast<const MyModel*>(index.model());

...
if(model != 0)
QString first = model->data(index, ItemRoles::First).toString(); // <-- debugger stops here

...
}



BTW, I don't see a need to get the model, if you need data of the index, you could use

QVariant QModelIndex::data ( int role = Qt::DisplayRole ) const

lanz
26th March 2013, 14:52
AFAIK, index.model () here returns proxy model and not underlying MyModel.
Anyway why do you need cast to MyModel if you're using model->data()?

jiveaxe
26th March 2013, 14:52
BTW, I don't see a need to get the model, if you need data of the index, you could use

QVariant QModelIndex::data ( int role = Qt::DisplayRole ) const

Very very thanks. Used your line and problem is fixed.