QTreeView:如何中止选择更改
Posted
技术标签:
【中文标题】QTreeView:如何中止选择更改【英文标题】:QTreeView: how to abort selection change 【发布时间】:2018-05-07 16:13:25 【问题描述】:我的小部件中有一个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);
但是,将当前索引设置回之前好像并没有 影响 TreeView;它仍然将新选择的项目显示为选中,并且 界面变得不连贯,因为详细信息中显示的项目是 不是树中选择的那个。
预期的行为是重新选择先前选择的项目,就好像没有 完全做出了新的选择。
【问题讨论】:
【参考方案1】:显然QTreeView
在调用currentChanged
插槽时忽略了选择模型的任何更新。
这里的解决方案是将插槽称为QueuedConnection
,因此connect
行将如下所示:
connect(
selection_model, &QItemSelectionModel::currentChanged,
this, &Editor::on_tree_selection_changed,
Qt::QueuedConnection // <-- connection must be queued.
)
这将确保选择模型的选择更改不会直接发生在插槽调用中。
【讨论】:
它不能做很多其他事情:毕竟,你的插槽代码正在运行。但真正发生的是你被编写伪同步代码咬了。对话处理程序属于一个插槽!如果你这样做了,你就永远不会遇到这个问题。 你能运行一个非同步的模态对话框吗? 是的,你可以。模态只是 UI 的一种特殊状态,它不会改变它的异步行为。像运行伪同步代码这样的特殊技巧只是把问题扫到了地毯下。以上是关于QTreeView:如何中止选择更改的主要内容,如果未能解决你的问题,请参考以下文章
QTableWidget 作为 QTreeView 中的子级
如何配置 QTreeView 以在使用箭头键移动时保留多项选择
在 PySide 的 QTreeView 中更改时如何获取项目的先前名称