PDA

View Full Version : QSortFilterProxyModel and QComboBox



Armin
21st February 2010, 09:58
Hi,
I want to sort a QComboBox locale aware, so I used a reimplementation of QSortFilterProxyModel. Unfortunately, it messes up the contents of the QComboBox if I insert Items after calling MyCombo->model()->sort(0);, which does not happen if I just use QSortFilterProxyModel without reimplementing it, so I guess my reimplementation is "naive" and something is missing/wrong.

In the example (stripped to the important stuff, but is compilable) I add A, C, B to the ComboBox, sort it, then I add D and the ComboBox shows <empty line>, A, B, D - and C is missing. Has anybody an idea what I did wrong reimplemnting QSortFilterProxyModel?

Thanks for your help
Armin

Files: (attached also as zip)

main.cpp


#include <QtGui/QApplication>
#include "mainwindow.h"

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}


mysortfilterproxymodel.h


#ifndef MYSORTFILTERPROXYMODEL_H
#define MYSORTFILTERPROXYMODEL_H

#include <QtGUI>

class MySortFilterProxyModel : public QSortFilterProxyModel
{
Q_OBJECT

public:
MySortFilterProxyModel(QObject *parent);
bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
};
#endif // MYSORTFILTERPROXYMODEL_H


mysortfilterproxymodel.cpp


#include "mysortfilterproxymodel.h"

MySortFilterProxyModel::MySortFilterProxyModel(QOb ject *parent) : QSortFilterProxyModel(parent)
{
}
//---------------------------------------------------------------------------
bool MySortFilterProxyModel::lessThan(const QModelIndex &left,
const QModelIndex &right) const
{
QVariant leftData = sourceModel()->data(left);
QVariant rightData = sourceModel()->data(right);

QString leftString = leftData.toString();
QString rightString = rightData.toString();

return QString::localeAwareCompare(leftString, rightString) < 0;
}


mainwindow.h


#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtGUI>
#include "mysortfilterproxymodel.h"

class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();

QComboBox *MyCombo;
MySortFilterProxyModel *MyProxySortModel;

};
#endif // MAINWINDOW_H


mainwindow.cpp


#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
MyCombo = new QComboBox(this);
MySortFilterProxyModel *MyProxySortModel = new MySortFilterProxyModel(MyCombo);
MyProxySortModel->setSourceModel(MyCombo->model());
MyCombo->model()->setParent(MyProxySortModel);
MyCombo->setModel(MyProxySortModel);

MyCombo->addItem("A", 1);
MyCombo->addItem("C", 3);
MyCombo->addItem("B", 2);

MyCombo->model()->sort(0);

MyCombo->addItem("D", 4);
}
MainWindow::~MainWindow() {}


4309

norobro
21st February 2010, 20:35
Sorry Armin after further testing I discovered my suggestion didn't work.

Lykurg
21st February 2010, 21:36
Some point I can add is, that with calling MyCombo->setModel(MyProxySortModel); the "sourceModel()" is deleted:
void QComboBox::setModel(QAbstractItemModel *model)
{
Q_D(QComboBox);
//...
if (d->model->QObject::parent() == this)
delete d->model; But even if you call a MyCombo->model()->setParent(this); before the problem is not solved...

norobro
21st February 2010, 23:09
I found an old thread (http://www.qtcentre.org/threads/3741-How-to-sort-a-QComboBox-in-Qt4) that states that this was fixed in Qt 4.2. Hmmmmm

I got it to work by using
MyCombo->insertItem(0,"D", 4); Of course this puts the "D" first so you have to resort. I also tried the following to put the item at the end of the list but got the same result as "addItem()"
MyCombo->insertItem(MyCombo->count(),"D", 4);

Lykurg
22nd February 2010, 09:21
I got it to work by using
MyCombo->insertItem(0,"D", 4); Of course this puts the "D" first so you have to resort. Instead of manually resort you can try QSortFilterProxyModel::setDynamicSortFilter().

Armin
22nd February 2010, 18:39
Hi norobro & Lykurg,

many thanks for your ideas, insertItem() instead of addItem() works fine, and dynamic sorting makes it easier. Do you agree that there must be some bug with addItem()? Hope that I can manage all other things which will come up in my little "Qt begiunners project" by myself without taking your time. Sorting things in Qt was/is really a challenge for me :-).

Have a nice day
Armin