selectionChanged()在删除第一行时的行为

时间:2017-06-22 22:27:24

标签: c++ qt qtablewidget selectionchanged qitemselectionmodel

请运行以下代码(我使用的是Qt 5.9):

QTableWidget* tableWidget = new QTableWidget(2, 2, nullptr);
tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
connect(tableWidget->selectionModel(), &QItemSelectionModel::selectionChanged,
   [&](const QItemSelection& selected, const QItemSelection& deselected) 
   { qDebug() << "selected =" << selected << endl << "deselected =" << deselected; });
tableWidget->show();
QTimer::singleShot(10000, [=](){ tableWidget->removeRow(0); });

在10秒内,选择两行中的第一行。您将看到调试输出。它会显示您的点击选择了第0行。 然后,在10秒后,自动删除第0行。调试输出现在显示选择了第1行并取消选择了第0行。

后者对我没有任何意义。当删除第0行时,我希望之后选择“新”第0行。视觉选择的行仍然是第0行,第1行根本不存在。

自定义模型和通用视图也会发生这种情况,并通过指向不存在的行使我的应用程序崩溃。

这是理想的行为吗?我的误解在哪里?

1 个答案:

答案 0 :(得分:0)

在删除之前更改所选行非常有意义。相反的做法可能导致读取悬空数据,例如,如果在模型更改但视图包含过期索引时刷新UI。

考虑两次删除第0行:第二次非常明显,在删除表中的最后一行之前,必须必须更改(在这种情况下取​​消选择)避免将无效索引作为选定行。

您可以使用以下修改示例来查看模型实际更新的时间。

import numpy as np
n = len(df)
df.loc[:,'industry'] = np.ones(n)
print(df)

解决方法

主要问题是,正如您在评论中指出的那样,您不能依赖信号信息:如果执行删除,那些auto tableWidget = new QTableWidget(2, 2, nullptr); tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); tableWidget->setSelectionMode(QAbstractItemView::SingleSelection); connect(tableWidget->selectionModel(), &QItemSelectionModel::selectionChanged, [&](const QItemSelection& selected, const QItemSelection& deselected) { qDebug() << "selected =" << selected << endl << "deselected =" << deselected; }); connect(tableWidget->model(), &QAbstractItemModel::rowsRemoved, [&](const QModelIndex &, int first, int last) { qDebug() << "first row removed =" << first << endl << "last row removed =" << last; }); tableWidget->show(); QTimer::singleShot(10000, [=](){ tableWidget->removeRow(0); }); QTimer::singleShot(15000, [=](){ tableWidget->removeRow(0); }); // remove twice 可能有效或无效。你可以跟踪所有的变化,但这将是令人筋疲力尽的。

相反,您可以尝试延迟选择信号,因此在处理模型时,模型已更新,您可以信任选择模型中的信息。 技巧是使用计时器:处理超时事件的函数将在事件循环的下一次迭代中执行(即使超时时间为0),同时模型和窗口小部件在当前迭代中更新

QModelIndex