0
votes

I have a QListView and QTableView both sharing a subclassed QSortFilterProxyModel on top of a custom source model. Sorting is enabled in the QTableView, how to share the same sorting result between two views?

Do I reimplement the sort() or lessThan() function of the QSortFilterProxyModel? If so, how should i reimplement them?

This is currently my code and it's not working:

MyModel *model = new QMyModel();
MySortFilterModel *proxy_model = new MySortFilterModel();
proxy_model->setSourceModel(model);
proxy_model->setDynamicSortFilter(true);

QListView *list = new QListView();
list->setModel(proxy_model);

QTableView *table = new QTableView();
table->setModel(proxy_model);
table->setSortingEnabled(true);

I have also tried the following:

QHeaderView *header = table->horizontalHeader();
header->setSortIndicator(0, Qt::AscendingOrder);
header->setSortIndicatorShown(true);
header->setSectionsClickable(true);
connect(header,SIGNAL(sectionClicked(int)),table,SLOT(sortByColumn(int)));

But when I sort the table by clicking the header, the table is updated but not the list, with both view having different items at different rows.

I would like to have a result such that when user clicks the horizontal header of the QTableView, the item data are sorted, meanwhile the same item data which are shared in the QListView are also being sorted.

1

1 Answers

0
votes

I was interested the question. So I created an empty GUI project and implemented something like your first example. It seems my code do what you want. When I click the table header the QListView items resorts.

You can try it

mainwindow.h:

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    void mySetupUi();

    Ui::MainWindow *ui;

    QSortFilterProxyModel *proxyModel;
    QStandardItemModel *sourceModel;

    QTableView *tableView;
    QListView *listView;
};

mainwindow.cpp:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    proxyModel(new QSortFilterProxyModel(this)),
    tableView(new QTableView(this)),
    listView(new QListView(this))
{
    ui->setupUi(this);

    sourceModel = getModel();

    // set source model for proxy
    proxyModel->setSourceModel(sourceModel);

    tableView->setSortingEnabled(true);

    // set proxy model for views
    tableView->setModel(proxyModel);
    listView->setModel(proxyModel);

    mySetupUi();
}

void MainWindow::mySetupUi()
{
    tableView->move(10, 15);
    listView->move(300, 15);

    tableView->adjustSize();
    listView->adjustSize();

    tableView->raise();
    listView->raise();
}

model initialization (you can put it near the mainwindow constructor):

QStandardItemModel* getModel()
{
    QStandardItemModel *model = new QStandardItemModel();

    model->setItem(0, 0, new QStandardItem("Alex"));
    model->setItem(0, 1, new QStandardItem("Brown"));
    model->setItem(0, 2, new QStandardItem("24"));

    model->setItem(1, 0, new QStandardItem("Mike"));
    model->setItem(1, 1, new QStandardItem("White"));
    model->setItem(1, 2, new QStandardItem("19"));

    model->setItem(2, 0, new QStandardItem("Ben"));
    model->setItem(2, 1, new QStandardItem("Black"));
    model->setItem(2, 2, new QStandardItem("22"));

    return model;
}

It looks as the same what you did. But it works.