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

Kind of RAII to manage GUI state in Qt

本文关键字:GUI 管理 状态 RAII Qt 一种      更新时间:2023-10-16

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

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

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

任何评论/建议都是非常欢迎的。

提前感谢,

费德里科•

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

的想法是,当您第一次进行更改时,您定义了一些想要在作用域的末尾运行的代码,其余的被处理。如果需要,您可以"取消"代码。

我想输入一个例子,但是我在手机上。

RAII用于处理资源,这并不像有些人可能让您相信的那样是一个受约束的概念。在很多情况下,"resource"可以用"state"代替。

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

你正确使用了RAII。

一定要给你的类起一个名字,让它清楚地表明你把可见性当作一种可丢弃的资源——也许是像VisibleStateIsVisibleContext这样简单的名字。

我已经完成了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)