QTreeView:如何中止选择更改

QTreeView: how to abort selection change

本文关键字:选择 何中止 QTreeView      更新时间:2023-10-16

我的小部件中有一个QTreeView。在视图中选择项目时,我有 在详细信息窗口中更新一系列信息小部件的信号处理程序 关于所选项目。然后,用户可以编辑项目详细信息并提交 更改回模型。

如果此选择更改时已编辑详细信息视图中的数据 发生,我在替换数据之前向用户显示一个确认对话框 选择新项目时。如果用户取消,我想设置 树又回到了以前的样子。

我的插槽连接得像这样:

auto selection_model = treeview->selectionModel();
connect(
selection_model, &QItemSelectionModel::currentChanged,
this, &Editor::on_tree_selection_changed
)

在我的插槽中,代码的结构如下:

void on_tree_selection_changed(QModelIndex const& index, QModelIndex const& previous)
{
if(not confirm_editor_discard()) 
{ 
// user does not want to override current edits
log.trace("cancel item selection change");
using SF = QItemSelectionModel::SelectionFlags;
auto sm = treeview->selectionModel();
sm->setCurrentIndex(previous, SF::SelectCurrent | SF::Rows);
}
else
{
// user wants to discard, so update the details view.
log.trace("discard pending edits");
set_details_from_model(index);
}
}

但是,当前索引的设置回到以前的索引似乎并没有 影响树视图;它仍然将新选择的项目显示为选定,并且 界面变得不连贯,因为详细信息中显示的项目是 不是在树中显示为选中的那个。

预期行为是重新选择先前选择的项目,好像没有 完全进行了新的选择。

显然,在调用currentChanged槽时,QTreeView会忽略选择模型的任何更新。

这里的解决方案是将插槽称为QueuedConnection,因此connect行如下所示:

connect(
selection_model, &QItemSelectionModel::currentChanged,
this, &Editor::on_tree_selection_changed,
Qt::QueuedConnection // <-- connection must be queued. 
)

这将确保选择模型的选择更改不会直接在时隙调用中发生。