在Qt中使用RAII管理GUI状态的类型

3

我想知道你是否认为在Qt中使用类似RAII的模式来管理GUI状态是合理的。所谓GUI状态是指以下内容:我有一些小部件(包括鼠标光标状态),我希望在离开某个方法后这些小部件可以(不)可见/启用/更改,而且我不想以这种方式将所有操作都放在一个巨大的try catch块中:

widget1->show();
...
widgetN->show();

try {
   ...
}
catch(...) {
   widget1->hide();
   ... 
   widgetN->hide();

   throw;
}

widget1->hide();
... 
widgetN->hide();

如果我创建一个对象,允许我在其构造函数中关联hide/setEnabled/setCursor函数(可能是boost函数),并在其析构函数中调用此关联函数(假设所有此函数可能抛出的异常都在析构函数中被忽略/丢失),我可以拥有更清晰的代码。这合理吗?我有什么看不到的问题吗?
欢迎任何评论/建议。
提前致谢,
Federico

这可能适合放在http://codereview.stackexchange.com上。 - Merlyn Morgan-Graham
3个回答

7

这是完全合理的。你要寻找的技术叫做ScopeGuard,在Boost中称为ScopeExit。

思路是在进行更改时首先定义一些代码,以便在作用域结束时运行它,并处理其余部分。如果需要,可以取消“解除”代码。

我想打个例子但是我现在在用手机。


2

RAII的作用是处理资源,但这个概念并不像一些人所认为的那样受限。在许多情况下,“资源”可以被替换成“状态”。

如果你将控件的可见性与存储的状态等同起来,并且需要安全地回收该状态(将其设置为不可见),那么在析构函数中重置它是正确的方法。

你正确地使用了RAII。

请确保给你的类命名一个明显的名称,以便清楚地表明你正在将可见性视为一种可处理的资源 - 可以简单地命名为VisibleStateIsVisibleContext


0

我已经使用C++ lambda和2个宏完成了。

#include <functional>

struct _Scope_Exit_ {
        inline _Scope_Exit_(const std::function<void ()> f): _f(f) {}
        inline ~_Scope_Exit_() { _f(); }
        const std::function<void ()> _f;
};

#define SCOPE_EXIT_CAT2(x, y) x##y
#define SCOPE_EXIT_CAT1(x, y) SCOPE_EXIT_CAT2(x, y)
#define SCOPE_EXIT _Scope_Exit_ SCOPE_EXIT_CAT1(_scope_Exit_, __COUNTER__)([this](){
#define SCOPE_EXIT_END });

要使用它,您必须在方法末尾在SCOPE_EXITSCOPE_EXIT_END之间定义要执行的块。
在您的示例中应该是:
widget1->show();
...
widgetN->show();

SCOPE_EXIT
   widget1->hide();
   ... 
   widgetN->hide();
SCOPE_EXIT_END

... (code inside your try)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接