【问题标题】:How to stop QComboBox/QSpinBox to emit signals when enabling/disabling them?如何在启用/禁用 QComboBox/QSpinBox 时停止发出信号?
【发布时间】:2017-01-04 09:15:03
【问题描述】:

我有一个小型 Qt 绘图应用程序,我正在启用/禁用基于“主”组合框的小部件(组合框/旋转框)。例如,假设 master 是combo1,它会根据currentIndex() 更改combo2 中的条目,启用/禁用spin1,并为spin1 设置一个值,如果combo1 中的某个条目是选择。不过,还有更多的小部件。

chat(及以后)的小讨论之后,我将Qt::QueuedConnection 与每个connect() 一起使用,但这并没有阻止重新启用的小部件在重新启用时发出信号。这导致我的许多connect() 都为所有重新启用的小部件执行,导致多个绘图,我想避免这种情况。就像现在一样,(几乎)所有小部件都在connect() 中使用plot(),因此它是一个插槽的多个信号。

我的问题:有没有办法在重新启用小部件时防止发出信号?我可以让plot() 使用一些bool 来检查绘图是否已执行并防止相同类型的进一步操作,但这仍然会导致小部件发出信号并运行plot(),即使检查会阻止实际的绘图,但这似乎不是要走的路。我还希望避免运行 installEventFilter() 或类似的,因为这很可能会比之前的修复更慢。

【问题讨论】:

  • @Trevir 是的,这有帮助。但我不得不为QSpinBox 选择editingFinished(),为QComboBox 选择activated(int)。如果您将此作为答案,我会将其标记下来。
  • 很高兴,它有帮助,但我不会把别人的功劳归功于他人 ;-)。

标签: c++ qt


【解决方案1】:

a comment 中已经提到的另一个选项是使用QObject::blockSignals

combo1->blockSignals(true);
// do what ever you need
combo1->blockSignals(false);

我发现它更易于使用和阅读。此外,在很多情况下您根本不知道/处理这些连接。

更新

从 Qt 5.3 开始,您还拥有 QSignalBlocker,它是 blockSignals 的异常安全包装器(在内部,它使用 RAII 来阻止构造函数中的信号并在销毁时将它们恢复到之前的状态):

{
  QSignalBlocker blocker{combo1}
  // do what ever you need
}

【讨论】:

    【解决方案2】:

    在每次连接之前使用断开连接以防止多个连接。始终允许断开未连接的插槽。

    disconnect(spinbox1,...);
    connect(spinbox1,...);
    

    也可以屏蔽信号,但我认为您需要第一个解决方案。

    来自 QtDocumentation:

    bool QObject::blockSignals(bool 块) 如果 block 为真,则该对象发出的信号将被阻塞(即,发出信号不会调用任何与之连接的东西)。如果block为false,则不会发生这种阻塞。

    【讨论】:

    • 这也是一个解决方案,它可能会很好地补充 editingFinished()activated(),因为我现在看到,虽然它按预期运行,但即使在旋转框中单击,或在绘图区域,将导致信号发射。我之前看过blockSignals(),但在这里似乎没有帮助。如果没有其他答案,我会标记这个,还有 Trevir 的评论。
    猜你喜欢
    • 1970-01-01
    • 2014-05-10
    • 2012-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-25
    • 1970-01-01
    相关资源
    最近更新 更多