我有一个被禁用的组合,但添加一个元素会发出currentIndexChanged(int)
信号。
我希望在禁用小部件时自然关闭信号,但事实并非如此。我知道有blockSignals(bool)
,但如果有许多小部件的信号必须在禁用时被阻止",blockSignals
将需要每个小部件的布尔状态。
如何禁用小部件禁用时发送的信号(并且不改变其blockSignals
状态)?
EDIT
为了澄清:由于这是一个小部件,用户在禁用它时无法与之交互,但在以编程方式更改小部件时会发出一些信号。就我而言,有两个有趣的信号:
currentIndexChanged(int)
和activated(int)
我的代码中的问题是我有时会以编程方式更改组合并希望它发出信号,有时它是通过交互改变组合的用户。这就是我使用currentIndexChanged
而不是activated
的原因。
在这两种情况下,无论如何,我都不希望在禁用小部件时发出信号。
答案 0 :(得分:2)
QComboBox
信号是基于最终用户观点的用户互动,如果您只有QComboBox
,而您的问题似乎并不存在任何其他内容。
我根本无法重现这个问题。我刚刚制作了一个简短的程序,我无法获取任何QComboBox信号,因为我无法简单地与小部件进行交互。
编辑:为随意读者提供更多上下文来提问您的问题可能是一个好主意,但基于评论中的进一步说明,是的,编程可能是这种情况,但随后发出信号使用相应的插槽也可能以编程方式进行处理,因此如果Qt自动阻止它们,这不是一个重大改进。
幸运的是,您希望拥有的功能已经可用:
bool QObject::blockSignals(bool block)
如果block为true,则此对象发出的信号被阻塞(即,发出信号不会调用与其连接的任何信号)。如果block为false,则不会发生此类阻塞。
返回值是signalsBlocked()的前一个值。
请注意,即使此对象的信号已被阻止,也会发出destroy()信号。
如果您想为许多小部件执行此操作,请创建一个您调用的简单函数,而不是myWidget->setDisabled(true);
:
inline bool disableAndBlockSignals(QWidget *widget)
{
widget->setDisabled(true);
return widget->blockSignals(true);
}
如果您只想停用部分内容,例如currentIndexChanged
,则可以手动使用disconnect。
答案 1 :(得分:1)
如果要阻止信号,可以使用QObject::disconnect();
断开信号,然后在想要取消阻止信号时重新连接信号。
答案 2 :(得分:0)
在您的情况下,信号是传递给其他对象的唯一状态信息源。如果禁用它们,其他对象将无法获得状态已更改的任何通知。这可能会导致对象中的错误,这些错误取决于被告知您的窗口小部件的状态。
至少有两种解决方案:
不要改变小部件的状态。您可以推迟更新小部件的内容,直到重新启用它为止。
创建一个监视原始窗口小部件状态的代理,并对信号进行排队(使用压缩),直到重新启用窗口小部件。
由于这些变通办法,您的设计可能需要返工。如果你可以应对来自那些禁用小部件的信号,也许它会更好。您还应评估禁用窗口小部件是否不会破坏用户体验。如果用户想要查看窗口小部件的内容,但并不意味着更改当前设置,该怎么办?在这种情况下,禁用的小部件太过分了。您可以使自己(可能是子类)窗口小部件动作,以便不禁用控件,但当前元素保持不变。这甚至可以是一个单独的对象,适用于任何控制 - 通过明智地利用用户属性。