我正在开发一个游戏编辑器。我想做的事情之一是显示游戏对象的信息,并在游戏中发生任何变化时更新它。
伪代码:
struct GameObject
{
//Some data over here
void AddDataListener(DataListener);
};
class GameObjectPanel:QWidget, DataListener
{
void Initialize()
{
//Create all UI elements and setup signals for them, this is called once when window first appears
//signals are setup so they call various versions of OnValueChanged()
}
void SetGameObject(GameObject*)
{
//Update the UI elements with the values from the game object
}
void OnDataChanged(GameObject*)
{
//Update all UI elements
}
slot OnValueChanged(...)
{
//Update the object
}
};
现在问题来了:每次调用OnValueChanged()时,它都会将更改应用于游戏对象,然后通知面板它发生了更改,面板随后更新所有UI元素,面板随后调用OnValueChanged(),面板随后更改对象,等等。
幸运的是,这个循环不会永久发生,因为值很快就稳定下来了(主要原因是转换,我有一个显示全局转换的小部件,但我存储了本地转换,所以每次全局转换小部件发生变化时,它都需要重新计算),但我认为这个循环根本不应该发生。
是否有一种方法可以订阅插槽,但只有当用户更改数据时才激活它们,或者是否有一种方法可以一次启用/禁用所有插槽?逐个检查每个连接并禁用它们,然后重新启用它们对我来说似乎不太可行,因为它们非常多,而且很容易错过。
我目前的解决方案包括添加一个“blockGameObjectSignals”布尔值,我在每次收到值更改信号时设置该布尔值,并且每次从游戏对象更新时都设置该布尔值,但这是大量重复性很强且容易出错的额外代码,因此如果知道是否有“正确”的方法来解决此问题,将非常有益。
提前感谢您的任何帮助!
1条答案
按热度按时间vc6uscn91#
在任一方法中:
OnDataChanged
或OnValueChanged
您可以在所考虑的对象上使用QSignalBlocker,以防止它们发射***changed
信号。这是一个常见的做法,UI元素之间有循环依赖关系,例如DEC-〉HEX和HEX-〉DEC转换器与2
QLineEdit
,其中一个改变,因为你在另一个键入。