Question

Let's assume, I have a list of points. One QTableView shows the list in Cartesian coordinates (x, y, z). Another QTableView shows the projection of every point to an arbitrarily chosen plane (x', y'). Now, I would like to share row selections between these two views. It should not matter, in which view the user edits the selection.

I am pretty sure that a QAbstractProxyModel derivative cannot be used right away, because the (x, y, z) cannot be transformed into (x', y') by simple index projections, or permutations.

Workaround: The two models for (x, y, z) and (x', y') are joined by a third model with (x, y, z, x', y') rows. Now, two QSortFilterProxyModels break up the joined columns, again. Every selection by any view is actually a selection of (x, y, z, x', y') rows, and therefore shared.

It seems clumsy, to write a whole model that joins columns, just to break them up again. However, synchronizing two selection models by connecting currentRowChanged, requires signal loop handling, and the QAbstractProxyModel interface does not to support multiple submodels. Is the workaround really the way to go? Or is there a better one?

Best regards, Marian

Additional information (edited April 2nd):

  • The solution should be robust under drag and drop of rows, too.
  • The solution should scale well, if I have more than two transformations. The views for the transformations can be used independently, or as I described sharing the selected rows.
Was it helpful?

Solution

Each QtableView has a Selection model. For each of the two QtableViews you can connect the signal currentChanged of the selection model to a slot change the selection of the other QtableView by setCurrentIndex. This can be done like:

QObject::connect(ui->tableView1->selectionModel(),SIGNAL(currentChanged(QModelIndex,QModelIndex)),this,SLOT(onCurrentChanged1(QModelIndex,QModelIndex)));

QObject::connect(ui->tableView2->selectionModel(),SIGNAL(currentChanged(QModelIndex,QModelIndex)),this,SLOT(onCurrentChanged2(QModelIndex,QModelIndex)));

void MyClass::onCurrentChanged1(QModelIndex curIndex, QModelIndex prevIndex)
{
    int newRow = curIndex.row();
    int curRow = ui->tabaleView2->selectionModel()->currentIndex().row();
    if( newRow != curRow )
    {
        QModelIndex newIndex = ui->tabaleView2->model()->index(row, 0);
        ui->tabaleView2->setCurrentIndex(newIndex);
    }
}
void MyClass::onCurrentChanged2(QModelIndex curIndex, QModelIndex prevIndex)
{
    int newRow = curIndex.row();
    int curRow = ui->tabaleView1->selectionModel()->currentIndex().row();
    if( newRow != curRow )
    {
        QModelIndex newIndex = ui->tabaleView1->model()->index(row, 0);
        ui->tabaleView1->setCurrentIndex(newIndex);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top