选择菜单操作时发送 QWidget 信号 - 如何防止这种情况?
在我的多个 Qt 应用程序中,我注意到,每当单击菜单栏时,在调用菜单操作之前,都会重新发送从 GUI 内的小部件发送的最后一个信号。大多数时候这并不重要;但在某些情况下它非常重要。
在少数情况下,小部件的信号连接到其自己的插槽之一,可以直接以
if (hasFocus())
{
// ...
}
... 块开始插槽,以便可以忽略此类虚假信号(不是由用户实际单击小部件生成的)。
然而,我最近发现这种行为导致了几个相关的错误,其中虚假信号在被执行之前会通过程序的多个层传递,因此简单地检查特定的小部件是否具有焦点实现起来并不容易。
因此,我的问题是:
到底为什么单击菜单项会导致屏幕上其他位置的小部件发出信号?我在任何地方都找不到此行为的记录?
我该如何停止它?
非常感谢,
斯蒂芬。
In more than one of my Qt applications I've noticed that, whenever the menu bar is clicked, the last signal to have been sent from a widget within the GUI is re-sent before the menu action is invoked. Most of the time this doesn't matter; but on some occasions it matters very much.
In a few cases where the widget's signal is connected to one of its own slots, it's straightforward to begin the slot with a
if (hasFocus())
{
// ...
}
...block so that such spurious signals, not generated by the user actually clicking on the widget, can be ignored.
However, I've recently identified that this behaviour is responsible for several related bugs where the spurious signals are passed on through several layers of the program before being acted upon, so simply checking whether a particular widget has focus is not trivial to implement.
My question, therefore, is:
why on earth does clicking on a menu item cause a signal to be emitted from a widget elsewhere on the screen? I can't find this behaviour documented anywhere?
how do I stop it?
Many thanks,
Stephen.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
正如您自己推断的那样,如果用户按 enter 并且
QLineEdit
稍后失去焦点,则QLineEdit::editingFinished
信号可以发出两次。创建了一个旧错误,但行为尚未更改:https://bugreports.qt.io/浏览/QTBUG-40。您的解决方案很好:重载 QLineEdit 并在触发信号之前检查值是否已更改。您可以使用
QLineEdit::isModified
标志进行检查:它的默认值为 false,并且每当用户更改行编辑的内容时就会更改为 true。当您发出信号时,必须手动将其重置为 false。您还可以在接收器对象中进行检查,只需检查该值是否有意义(例如与最后记录的值不同)并处理它。
因此污染信号不会成为问题。在我看来,这是最干净的解决方案,然后你就有了一个强大的模型。因为用户还可以使用相同的文本值多次点击 enter,而您无论如何都必须处理这个问题。
您还可以使用 QLineEdit::returnPressed,但这要求用户始终按 Enter 来验证值。并不总是直观的,但会迫使用户显式验证输入。
As you deduced yourself, the
QLineEdit::editingFinished
signal can be emitted twice if the user press enter and theQLineEdit
loses the focus later. An old bug was created but behaviour has not been changed : https://bugreports.qt.io/browse/QTBUG-40.Your solution is fine : overload QLineEdit and check if the value has changed before triggering the signal. You can use the flag
QLineEdit::isModified
for the check : it has a default value of false and is changed to true whenever the user changes the line edit's contents. It has to be manually reset to false when you emit the signal.You can also do that check in the receiver object, just checking if the value has a meaning (is different from the last recorded value for example) and process it or not.
Therefore the polluting signals would not be a problem. It is in my opinion the cleanest solution, then you have a robust model. Because the user could also hit enter a few times with the same text value and you have to handle this anyway.
You can also use
QLineEdit::returnPressed
but this requires the user to always press enter to validate a value. Not always intuitive but forces the user to explicitly validate the inputs.