1

我有两个 QTableWidget,具有相同的行数和列数。现在,一个表中的每个选择都应该自动更新另一个表中的选择,反之亦然。

以下代码可以正常工作,但有一个例外:

#include <QApplication>
#include <QTableWidget>
#include <QHBoxLayout>
#include <functional>

QTableWidget* create() {
    auto table = new QTableWidget;
    table->setSortingEnabled(true);
    table->setRowCount(20);
    table->setColumnCount(1);
    for (auto i = 0; i < 20; i++) {
        {
            auto item = new QTableWidgetItem(QString("%1").arg(i+1));
            table->setItem(i, 1, item);
        }
    }
    return table;
}
int main(int argc, char** args) {
    QApplication app(argc, args);

    QTableWidget* table1 = create();
    QTableWidget* table2 = create();
    auto frame = new QFrame;
    frame->setLayout(new QHBoxLayout);
    frame->layout()->addWidget(table1);
    frame->layout()->addWidget(table2);
    frame->show();
    auto func = [&](QTableWidget* senderTable, QTableWidget* receiverTable) {
        const QSignalBlocker blocker(receiverTable);
        receiverTable->selectionModel()->clearSelection();
        for (auto item : senderTable->selectedItems()) {
            receiverTable->item(item->row(), item->column())->setSelected(true);
        }
    };

    QObject::connect(table2, &QTableWidget::itemSelectionChanged, std::bind(func, table2, table1));
    QObject::connect(table1, &QTableWidget::itemSelectionChanged, std::bind(func, table1, table2));
    app.exec();
}

如果我对一列进行排序,则会发生异常。在这种情况下,wrong项目在另一个表中被选中。

如果启用排序,则会发生错误选择。

换句话说,选择同步的行为应该独立于选择的排序。我的表格的内容只是示例。

实现所需行为的最简单方法可能是什么?

4

1 回答 1

0

我已经修改了您的示例以使其按预期工作。我们的想法是我们不应该依赖项目的行和列,而是在每个项目中存储一些唯一标识符并执行查找,而不是按该标识符而不是按行和列,这可能因排序顺序而异。

所以,这里是演示我所说的代码:

#include <QApplication>
#include <QTableWidget>
#include <QHBoxLayout>
#include <functional>
#include <assert.h>

QTableWidget* create()
{
  auto table = new QTableWidget;
  table->setSortingEnabled(true);
  table->setRowCount(20);
  table->setColumnCount(1);
  for (auto i = 0; i < 20; i++) {
    auto item = new QTableWidgetItem(QString("%1").arg(i + 1));
    item->setData(Qt::UserRole, i); // It can be any kind of unique identifier.
    table->setItem(i, 1, item);
  }
  return table;
}

int main(int argc, char** args)
{
  QApplication app(argc, args);

  QTableWidget* table1 = create();
  QTableWidget* table2 = create();
  auto frame = new QFrame;
  frame->setLayout(new QHBoxLayout);
  frame->layout()->addWidget(table1);
  frame->layout()->addWidget(table2);
  frame->show();
  auto func = [&](QTableWidget* senderTable, QTableWidget* receiverTable) {
    const QSignalBlocker blocker(receiverTable);
    receiverTable->selectionModel()->clearSelection();
    auto model = receiverTable->model();
    for (auto item : senderTable->selectedItems()) {
      // Find the item with the same identifier.
      auto found = model->match(model->index(0, 0), Qt::UserRole, item->data(Qt::UserRole));
      assert(!found.empty());
      auto idx = found.first();
      receiverTable->item(idx.row(), idx.column())->setSelected(true);
    }
  };

  QObject::connect(table2, &QTableWidget::itemSelectionChanged, std::bind(func, table2, table1));
  QObject::connect(table1, &QTableWidget::itemSelectionChanged, std::bind(func, table1, table2));
  app.exec();
}
于 2018-01-04T14:31:46.520 回答