在Qt中管理GUI状态的RAII种类

时间:2011-08-01 18:06:22

标签: c++ user-interface qt4 design-patterns

我想知道您是否认为使用类似于RAII的模式来管理Qt中的GUI状态是合理的。通过GUI状态我的意思是:我有一些小部件(包括鼠标光标状态)我想离开某些方法后我想去(不)可见/启用/改变,我不想把我所做的一切都放在一个巨大的尝试抓住这种方式:

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

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

   throw;
}

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

如果我创建一个对象,允许我将hide / setEnabled / setCursor函数(可能是一个boost函数)与其构造函数关联,并在其析构函数上调用此关联函数(前提是此函数可以抛出的所有异常都被吃掉/在析构函数中丢失了)我可以拥有更清晰的代码。这合理吗?我没看到什么?

任何意见/建议都会受到欢迎。

提前致谢,

费德里科

3 个答案:

答案 0 :(得分:7)

这是完全合理的。您所追求的技术称为ScopeGuard,在Boost中称为ScopeExit。

我们的想法是,当您第一次进行更改时,您要在范围的末尾定义要运行的代码,然后处理其余的代码。如果需要,您可以“解雇”代码。

我会输入一个例子,但我正在打电话。

答案 1 :(得分:2)

RAII用于处理资源,这并不像某些人可能认为的那样受到限制。在许多情况下,“资源”可以用“状态”代替。

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

您正确使用RAII。

请务必为您的课程命名,明确表示您将可见性视为一次性资源 - 可能就像VisibleStateIsVisibleContext一样简单。

答案 2 :(得分: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)