我有两个QTableWidgets,具有相同的行数和列数。现在,一个表中的每个选择都应该自动更新另一个表中的选择,反之亦然。
以下代码正常,但有一个例外:
#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
项。
换句话说,选择同步的行为应该与所选的排序无关。我的表格的内容只是一些例子。
实现理想行为的最简单方法是什么?
答案 0 :(得分:0)
我修改了您的示例,使其按预期工作。我们的想法是,我们不应该依赖于物品&#39;行和列,而是在每个项目中存储一些唯一标识符,而不是按行和列执行查找,而不是按行和列执行查找,具体取决于排序顺序。
所以,这是代码,它演示了我所说的内容:
#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();
}