我通常习惯于.NET框架,最近有机会使用C /QT进行项目。在这种情况下,我想实现以下功能:(为了简化事物,请说我有一个listView和textbox/textedit)
- 如果我选择了listView的项目 ->在textedit (完成) 中显示相应的文本
- 如果我编辑文本,然后单击列表中的另一个项目 ->显示一个询问是否保存或取消更改(完成)的对话框。textedit从列表中获取信号,告知所选项目已更改。
- 如果用户按下保存 ->将其保存回去并刷新列表中的项目,则在列表(完成) 中选择了用户单击的新项目
- 如果用户按CANCAL->请勿选择用户单击的其他项目(这是我的问题是)
基本上我看到了两个解决方案(可能还有更多):
- 将信号从textedit发送回列表,告诉列表以还原上一个选择。我个人不太喜欢这个解决方案,因为我必须将它们更强大(列表向Textedit发送信号,现在也相反)。另外,这种"强迫"选择恢复可能再次触发后续信号,该信号必须再次阻止...
- 一个更好的解决方案(我认为)是在信号中拥有一些否决权。我可以想象列表要发送两个信号:
- 让我们呼叫第一个
aboutToChangeSelection(proposedSelection, vetoObj)
- 完成操作后的另一个:
changedSelection(newSelection)
- 让我们呼叫第一个
第一个信号将发送到TextEdit,然后最终将使用其否决权。之后,将同一信号发送到列表本身,根据否决权执行操作,并在第二个信号实际更改选择时发送。
在.NET世界中,存在这种机制,借助CancelEventArgs
。我知道.NET事件和QT信号具有完全不同的工作原理,但是是否有相同效果的QT?
非常感谢您的任何帮助!
如果您使用的是QListWidget
而不是QListView
,则可以执行以下操作:
- 听信号:
QListWidget::itemPressed ( QListWidgetItem * item )
,而不是信号说该物品已更改(即currentItemChanged ( QListWidgetItem * current, QListWidgetItem * previous )
) - 打开对话框的函数是连接到此信号的插槽。我认为它不需要修改。
- 收听信号:
currentItemChanged ( QListWidgetItem * current, QListWidgetItem * previous )
,它将仅用于记住当前和最后一项。 - 现在,在您的情况下,当用户集取消时,将编程性更改回最后一项。
现在有一个问题。首先将收到哪个信号?未在文档中指定,并且可以按任何顺序进行。如果用户在项目A
上,然后单击项目B
,则希望LastItem为A
,并且当前项目为B
,您正在处理itemPressed
。因此,您想先处理currentItemChanged
。幸运的是,您可以将Qt::DirectConnection
用于currentItemChanged
,然后将Qt::QueuedConnection
用于itemPressed
替代:
您可以在列表小部件上使用事件过滤器。该过滤器将是执行您在几个步骤中描述的处理的一种过滤器。如果用户点击接受,则将事件发送到列表视图。如果用户拒绝,则阻止事件。我不确定,但是可能不会在过滤器中处理这些事件,这将使此替代性不可行。
不是100%确定的,但是您可以覆盖QCoreApplication::notify( QObject * receiver, QEvent * event )
并尝试找到正确的事件,然后在其中调用ignore()
。要告诉何时忽略,您可以添加一个新的QEvent
子类,将目标元素指针嵌入其中并使其充当您的否决事件 - 如果收到的话,您知道您将忽略下一个特定类型的事件,为此特定对象。