Russian Qt Forum

Qt => Кладовая готовых решений => Тема начата: Bepec от Май 22, 2013, 10:33



Название: Накрываем виджеты стеклом. Эффект блокировки виджета.
Отправлено: Bepec от Май 22, 2013, 10:33
Краткая предыстория:
Часто при разработке приложений сильно зависящих от ресурсов (серверов, устройств, файлов и т. п.), возникает необходимость сообщить пользователю об их недоступности. А иногда и полностью заблокировать работу с приложением до освобождения или начала работы ресурса. Такая необходимость возникает при создании различных тонких клиентов.

Что сподвигло:
Статей на эту темы много. А готовых продуктов я, когда было необходимо, не нашёл. Заодно подправлю оформление кода, если будут критики.

Что получилось:
Взяв за основу статью VaiMR (ссылка в конце сообщения) и собственную мотивацию я сделал завершённый класс.
Возможно он имеется у каждого программиста в том или ином виду.

Здесь же я привожу готовый к употреблению продукт с исходниками и тестовой программой.

Так же материал будет полезен для новичков из-за простоты кода и русских комментариев.

Данный класс написан под Qt 4.7.2 работоспособен  с версии Qt 4.7.2 и до Qt 5.9.2. В архиве имеется файл проекта VS2008 плюс стандартный pro файл. Исходники переведены в UTF-8.
Отзывы пожелания комментарии оставляйте, буду рад.

Ссылка на статью VaiMR - http://www.quizful.net/post/glass-qt-component (более подробное описание слотов и пошаговое пояснение).

Архив запаролен. Пароль: "prog.org.ru" без кавычек.

update: исправлен баг - не блокировались event's на виджете жертве.

update 2: внесены правки и проверена работа под minGW, MSVC. Внесены отредактированные правки gil9red. Перезалито.


Название: Re: Накрываем виджеты стеклом. Эффект блокировки виджета.
Отправлено: GreatSnake от Май 22, 2013, 11:16
А теперь добавь аккселератор на какой нибудь контрол, например, на кнопку, и увидишь как "разобъётся" твое "стекло")
Решение не самое простое, подсказывать пока не буду)


Название: Re: Накрываем виджеты стеклом. Эффект блокировки виджета.
Отправлено: Bepec от Май 22, 2013, 11:59
Акселератор имеется в виду сочетание клавиш? Расшифруйте пожалуйста )


Название: Re: Накрываем виджеты стеклом. Эффект блокировки виджета.
Отправлено: GreatSnake от Май 22, 2013, 12:02
Акселератор имеется в виду сочетание клавиш? Расшифруйте пожалуйста )
Hot-key, QShortcut


Название: Re: Накрываем виджеты стеклом. Эффект блокировки виджета.
Отправлено: Bepec от Май 22, 2013, 12:49
Решение довольно простое - я не блокировал события в eventFilter. Что и послужило причиной пробега событий :D Перезаливаю архив.


Название: Re: Накрываем виджеты стеклом. Эффект блокировки виджета.
Отправлено: gil9red от Август 16, 2013, 19:57
Компилятор gсс 4.6.2
Ошибка: taking address of temporary [-fpermissive]

Строка 160: wGlass_->setGraphicsEffect(&QGraphicsOpacityEffect());
Жалуется на &QGraphicsOpacityEffect()
Лечится
Код:
QGraphicsOpacityEffect off;
wGlass_->setGraphicsEffect(&off);

Строка 223: wAnimationContainer_->setMovie(&QMovie());
Такая же жалоба :)
Лечение:
Код:
QMovie off;
wAnimationContainer_->setMovie(&off);


Название: Re: Накрываем виджеты стеклом. Эффект блокировки виджета.
Отправлено: Bepec от Август 16, 2013, 20:04
Версию Qt приведи пожалуйста :)

PS ты надеюсь понимаешь, что подобной правкой ты создаёшь утечку памяти в двух местах?

PPS удивлён что ругается. Видимо всё таки версия Qt другая. Уточни.


PPPS Может это варнинг, а не еррор? Компилятор прав, объект уничтожится в конце функции, но это не смертельно как бы.

update: Это особенность gcc. Вместо варнинга или молчания, как другие компиляторы, он ставит еррор.

Лечение - припиши флаг -fpermissive компилятору.

 


Название: Re: Накрываем виджеты стеклом. Эффект блокировки виджета.
Отправлено: kambala от Август 16, 2013, 20:38
слотам в SBControl неплохо бы дать вменяемые названия


Название: Re: Накрываем виджеты стеклом. Эффект блокировки виджета.
Отправлено: Bepec от Август 16, 2013, 20:42
Кхм, учту. Делалось в виде примера. для использования - тут важен сам glass.

Ещё замечания есть?


Название: Re: Накрываем виджеты стеклом. Эффект блокировки виджета.
Отправлено: gil9red от Август 16, 2013, 22:28
PS ты надеюсь понимаешь, что подобной правкой ты создаёшь утечку памяти в двух местах?
Лечение - припиши флаг -fpermissive компилятору.  

Первое, что пришло в голову ;D
Хотелось просто увидеть, как работает )

А так заменил бы на:
Код:
QGraphicsOpacityEffect off;
wGlass_->setGraphicsEffect(&off);
и
Код:
QMovie off;
wAnimationContainer_->setMovie(&off);

Исправил предыдущее свое сообщение :)


Название: Re: Накрываем виджеты стеклом. Эффект блокировки виджета.
Отправлено: gil9red от Август 16, 2013, 22:32
Ещё замечания есть?

Желательно бы сам пример отделить от файлов glass :)
sbclass и sbcontrol очень похожие, и пока в коде не полазил, думал что sbcontrol обязателен для работы glass )


Название: Re: Накрываем виджеты стеклом. Эффект блокировки виджета.
Отправлено: Bepec от Август 16, 2013, 22:34
Понятно. Комбинированные операторы gcc не жрёт. Поправлю ради пущей совместимости.

А про отделение - посмотрю.


Название: Re: Накрываем виджеты стеклом. Эффект блокировки виджета.
Отправлено: gil9red от Август 16, 2013, 22:50
Вот еще :)
Поместил я glass на QTableView, но скроллы не были закрыты, так должно быть? )

Код:
    glass = new SBGlass(ui->tableView);
    glass->install(ui->tableView);
    glass->enableOpacity();
    glass->enableColor();


Название: Re: Накрываем виджеты стеклом. Эффект блокировки виджета.
Отправлено: gil9red от Август 16, 2013, 22:53
Еще кое что нашел, связанно с изменением размера виджета, накрытого стеклом :)
Сплиттером подвигал и заметил вот такое интересное явление :)

Так и было задуманно? :)


Название: Re: Накрываем виджеты стеклом. Эффект блокировки виджета.
Отправлено: gil9red от Август 16, 2013, 23:12
Еще кое что нашел, связанно с изменением размера виджета, накрытого стеклом :)
Сплиттером подвигал и заметил вот такое интересное явление :)

Так и было задуманно? :)

В функции bool SBGlass::eventFilter(QObject* /* object */, QEvent* event)
изменил строку 80 на return parent()->eventFilter(this, event); и такое явление пропало =)



Название: Re: Накрываем виджеты стеклом. Эффект блокировки виджета.
Отправлено: Bepec от Август 17, 2013, 10:06
Скроллы видимо не учитываются. Это бага :D

А если исправить вашу строчку, то виджет под стеклом станет доступным - нажатия, клики мышкой, клавиши - он будет полностью работоспособным. Это плохо :D Смысла от стекла нет.


Название: Re: Накрываем виджеты стеклом. Эффект блокировки виджета.
Отправлено: gil9red от Август 17, 2013, 15:28
Код:
// Реализуем фильтр событий на виджете. Назначение этого фильтра - не
// допустить работу с виджетом под стеклом и обеспечить актуальные размеры и перерисовку стекла
bool SBGlass::eventFilter(QObject* /* object */, QEvent* event)
{
    // Если показывается виджет или изменились его размеры, изменяем размеры
    // стекла и позиционируем информационный блок
    if ((event->type() == QEvent::Show) || (event->type() == QEvent::Resize))
    {
        wGlass_->resize(wGlass_->parentWidget()->size());
        wGlass_->move(0, 0);
        infoBlockPositioning();
        return parent()->eventFilter(this, event);
    }
...
}

Родительский виджет же сможет менять размер и только :)
Другие события до него будут блокированы glass'ом :)
Или я что то не помнимаю? :)


Название: Re: Накрываем виджеты стеклом. Эффект блокировки виджета.
Отправлено: Bepec от Август 17, 2013, 15:38
М... Надо подумать, посмотреть. По идее это родитель посылает дитятке изменение размера. А возвращая родителю, мы эм... рекурсию не вызовем?

Т.е. родитель изменяет размер, посылает евент дитятку накрытому стеклом, а дитятко пуляет евент родителю, а родитель смотрит - евент то дитятку предназначен и пошло погнало. Не?


Название: Re: Накрываем виджеты стеклом. Эффект блокировки виджета.
Отправлено: gil9red от Август 17, 2013, 19:26
Была бы рекурсия, прога бы сразу после запуска упала бы :)

Или дело в том, что у меня родитель не является основным окном, потому и не появляется рекурсия (


Название: Re: Накрываем виджеты стеклом. Эффект блокировки виджета.
Отправлено: kamre от Август 17, 2013, 20:29
update: Это особенность gcc. Вместо варнинга или молчания, как другие компиляторы, он ставит еррор.

Лечение - припиши флаг -fpermissive компилятору.
Это особенность стандарта C++ (http://stackoverflow.com/questions/1565600/how-come-a-non-const-reference-cannot-bind-to-a-temporary-object), просто gcc лучше ему следует, а MSVC имеет расширения, которые включены по умолчанию.


Название: Re: Накрываем виджеты стеклом. Эффект блокировки виджета.
Отправлено: gil9red от Август 17, 2013, 20:47
Ясно =)
Интересное чтиво )


Название: Re: Накрываем виджеты стеклом. Эффект блокировки виджета.
Отправлено: Bepec от Август 17, 2013, 22:09
Я бы сказал так - gcc настолько следует стандарту, что зачастую проги, собранные на нём отказываются компилироваться в msvc :D Это я знаю точно.

PS если кто не понял, это сарказм.


Название: Re: Накрываем виджеты стеклом. Эффект блокировки виджета.
Отправлено: neversleep от Август 17, 2013, 22:16
Я бы сказал так - gcc настолько следует стандарту, что зачастую проги, собранные на нём отказываются компилироваться в msvc :D Это я знаю точно.

PS если кто не понял, это сарказм.
К чёрту msvc, дайошь gcc.

(Ну все поняли)


Название: Re: Накрываем виджеты стеклом. Эффект блокировки виджета.
Отправлено: Bepec от Март 10, 2018, 15:33
Предложения, претензии, инициативы предлагайте, пишите, излагайте :D


Название: Re: Накрываем виджеты стеклом. Эффект блокировки виджета.
Отправлено: AkonResumed от Октябрь 18, 2020, 20:19
Как ваше стекло соотносится с флагами Qt::WindowTransparentForInput, Qt::WA_TransparentForMouseEvents, Qt::WA_NoMousePropagation?