Тип RAII для управления состоянием GUI в Qt - PullRequest
3 голосов
/ 01 августа 2011

Я хотел бы знать, считаете ли вы разумным использование шаблона, аналогичного RAII, для управления состоянием GUI в Qt. Под состоянием графического интерфейса я имею в виду следующее: у меня есть некоторые виджеты (включая состояние курсора мыши). Я хочу, чтобы (не) был виден / включен / изменен после выхода из какого-либо метода, и я не хочу помещать все, что я делаю, в гигантская попытка поймать таким образом:

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

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

   throw;
}

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

Если я создаю объект, который позволяет мне связать функцию hide / setEnabled / setCursor (возможно, буст-функтор) с ее конструктором и которая вызывает эту связанную функцию с деструктором (при условии, что все исключения, которые может вызвать эта функция, съедаются / потерял в деструкторе) У меня может быть намного чище код. Это разумно? что я не вижу?

Любой комментарий / предложение будет приветствоваться.

Заранее спасибо,

Federico

Ответы [ 3 ]

7 голосов
/ 01 августа 2011

Это вполне разумно.Техника, которую вы ищете, называется ScopeGuard, она называется ScopeExit в Boost.

Идея состоит в том, что вы определяете некоторый код, который хотите запустить, в конце области, когда вы впервые вносите свои изменения, а остальное обрабатывается.Вы можете «отклонить» код, если хотите.

Я бы напечатал пример, но я на своем телефоне.

2 голосов
/ 01 августа 2011

RAII предназначен для утилизации ресурсов, что не является такой уж ограниченной концепцией, как некоторые могут поверить. «ресурс» может быть заменен на «состояние» во многих контекстах.

Если вы приравниваете видимость элемента управления к сохраненному состоянию, и вам нужно безопасно восстановить это состояние (установить его невидимым), тогда сброс его в деструкторе - это то, что нужно.

Вы правильно используете RAII.

Обязательно назовите свой класс чем-то, что делает очевидным, что вы рассматриваете видимость как одноразовый ресурс - возможно, такой простой, как VisibleState или IsVisibleContext.

0 голосов
/ 05 июня 2014

Я сделал с C ++ лямбда и 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_EXIT и SCOPE_EXIT_END

В вашем образце будет:

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

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

... (code inside your try)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...