Название: Временно блокировать рисование объекта Отправлено: Igors от Сентябрь 29, 2010, 19:16 Добрый вечер
Извиняюсь за явно неудачное название темы. Есть массив данных, каждый элемент довольно сложная структура. Элементы могут рисоваться во многих окнах и очень по-всякому. В какой-то момент получена команда: (пере) создать один из элементов. Это модальный процесс, но все же окна обновлять надо (напр переключились на др. задачу и обратно). Проблема в том что когда идет процесс создания элемента - рисовать его нельзя, нужные данные отсутствуют, вылетаем. Понятно что решение не одно. Напр. можно завести для элемента флажок locked и если взведен - не рисуем. Но мне это не очень нравится - придется вставлять эту проверку во все (разнообразные) рисования. Какие есть еще возможности? Спасибо Название: Re: Временно блокировать рисование объекта Отправлено: Akon от Сентябрь 29, 2010, 22:06 Не совсем понятна проблема.
Элемент данных изменился/создался/удалился - бросается сигнал, в окнах слоты и далее обновление окон. Что за специфика? Название: Re: Временно блокировать рисование объекта Отправлено: Igors от Сентябрь 29, 2010, 23:16 Не совсем понятна проблема. Изменение может занимать несколько минут. В это время пользователю запрещается что-то нажимать (кроме кнопки Cancel), но отрисовывать окна все равно надоЭлемент данных изменился/создался/удалился - бросается сигнал, в окнах слоты и далее обновление окон. Что за специфика? Название: Re: Временно блокировать рисование объекта Отправлено: Akon от Сентябрь 30, 2010, 10:38 Я так понимаю, что когда приходит время рисовать окно, объект данных может находится в незавершенном состоянии (длится несколько минут) и рисовать его нельзя.
Можно в объекте данных генерировать события: Код: Q_SIGNALS: Соответственно: updating() - рисуешь что-то типа "Ждите..." (как правило, напрямую через QWidget::repaint()); duringUpdate() - если все в главном потоке, то обрабатываешь сообщения (QCoreApplication::ProcessEvents()), чтобы была возможность нажать на кнопку Cancel; также можешь выводить процент выполнения; updated() - вожделенная отрисовка. Название: Re: Временно блокировать рисование объекта Отправлено: navrocky от Сентябрь 30, 2010, 13:07 Можно менять долго копию объекта, а в конце по ОК быстро вставить в основную структуру...
Наверное, правильного решения здесь нет, все зависит от трудозатрат/существующей реализации/ и пр факторов Название: Re: Временно блокировать рисование объекта Отправлено: Igors от Сентябрь 30, 2010, 13:24 Можно в объекте данных генерировать события: В данном случае объект пассивен, окно знает контейнер объектов которые надо нарисоватьКод: Q_SIGNALS: Можно менять долго копию объекта, а в конце по ОК быстро вставить в основную структуру... Это выглядит хорошо, но обойтись оператором = не удается. Объект зарегистрирован, его удаление вызывает запись undo на диск и.т.п. А вот "заблокировать" объект достаточно легко.Код
Все вызывающие проверяют возвращаемое значение на ноль, рисование безопасно. Но ведь "создающие" тоже пользуются тем же GetDisplayData, по сути они его и заряжают. Название: Re: Временно блокировать рисование объекта Отправлено: Akon от Сентябрь 30, 2010, 14:11 Обычно, если объектов много (их неэффективно делать QObject'ами), то активен QObject контейнер. В сигналах контейнера будут передаваться объекты. Без сигналов все равно не обойтись.
Название: Re: Временно блокировать рисование объекта Отправлено: Igors от Сентябрь 30, 2010, 15:06 Обычно, если объектов много (их неэффективно делать QObject'ами), то активен QObject контейнер. В сигналах контейнера будут передаваться объекты. Без сигналов все равно не обойтись. Не очень понятно кто кому сигналит :) Если все сводится к ф-ции-члену типа CanBeDrawn (по существу флажок предложенный в #1), то меня это не устраивает, если нужно расскажу почему. Если имеется ввиду что-то другое - поясните.Название: Re: Временно блокировать рисование объекта Отправлено: Akon от Сентябрь 30, 2010, 20:28 Окна отображают данные с контейнера. В контейнере что-то изменяется/добавляется/удаляется. Как окна узнают об этом? Посредством подписки на сигналы с контейнера. Короче паттерн "Наблюдатель". Я это имел ввиду.
В твоем случае, поскольку процесс обновления длительный и с Cancel'ом, вместо одного сигнала я предложил три. Под контейнером я понимаю объект логики, а не что-нибудь примитивное вроде QList. Название: Re: Временно блокировать рисование объекта Отправлено: Igors от Сентябрь 30, 2010, 20:43 Окна отображают данные с контейнера. В контейнере что-то изменяется/добавляется/удаляется. Как окна узнают об этом? Посредством подписки на сигналы с контейнера. Короче паттерн "Наблюдатель". Я это имел ввиду. Ну эффект 3-х тот же. Окно не может разбираться с каждым объектом индивидуально - нет смысла т.к. объекты могут перекрывать друг друга произвольным образом. Поэтому реально окно рисует все объекты контейнера. И если какой-то объект не готов - рухнет В твоем случае, поскольку процесс обновления длительный и с Cancel'ом, вместо одного сигнала я предложил три. Название: Re: Временно блокировать рисование объекта Отправлено: Akon от Сентябрь 30, 2010, 21:08 Объекты обновляются в своем потоке или GUI'шном?
Название: Re: Временно блокировать рисование объекта Отправлено: Igors от Сентябрь 30, 2010, 21:25 Объекты обновляются в своем потоке или GUI'шном? Здесь все просто в главной нитке - но это не делает жизнь легче :)Название: Re: Временно блокировать рисование объекта Отправлено: Alex_cs_gsp от Сентябрь 30, 2010, 21:40 Но мне это не очень нравится - придется вставлять эту проверку во все (разнообразные) рисования. Какие есть еще возможности? Спасибо А если эти все разнообразные рисования вывести через наследование? - тогда пусть флажок в базовом классе проверяется. Например Код: class CBase А когда нужна перерисовка, вызывать метод _DoPrint() ? Или как-то так. Название: Re: Временно блокировать рисование объекта Отправлено: Igors от Сентябрь 30, 2010, 21:52 А если эти все разнообразные рисования вывести через наследование? - тогда пусть флажок в базовом классе проверяется. Завести флажок (метод, сигнал) - не вопрос. Проблема в том что проверять его придется из очень многих мест. Во-первых, рисующих окон не одно, и даже не 10 (хотя одновременно открытых обычно немного). Во-вторых, объект может участвовать в рисовании неявно. Пример: должно рисоваться "нечто среднее" между 2-мя объектами (морф). Тогда сами объекты не рисуются, но чтобы получить это среднее - надо иметь DisplayData каждого, т.е. проблема та же. Название: Re: Временно блокировать рисование объекта Отправлено: Alex_cs_gsp от Сентябрь 30, 2010, 21:58 А через фильтр сообщений не получится?
Название: Re: Временно блокировать рисование объекта Отправлено: Akon от Сентябрь 30, 2010, 22:01 Выведи обработку рисования в кокой-нибудь отдельный класс. Он будет проверять флаги и т.п., а предоставлять максимально удобный интерфейс для отрисовки. Окна будут юзать этот класс.
Приведу пример для предложенного мной решения: допустим, есть окно, отображающее графический файл. Файл загружается по сети долго. Сервер обновляет данный файл. Пользователь нажимает кнопку "обновить". Команда идет в контейнер, тот выбрасывает сигнал updating(). Окно сразу же стирается и пишется "Loading... 0%". Далее по мере загрузки контейнер периодически бросает сигнал duringUpdate(). Соответственно в окне "Loading... 1%" и т.д. Когда файл будет загружен, контейнер бросает сигнал updated(), и окно отображает файл. Название: Re: Временно блокировать рисование объекта Отправлено: Igors от Сентябрь 30, 2010, 22:21 А через фильтр сообщений не получится? Каким образои?Выведи обработку рисования в кокой-нибудь отдельный класс. Он будет проверять флаги и т.п., а предоставлять максимально удобный интерфейс для отрисовки. Окна будут юзать этот класс. Базовый класс есть, но "что рисовать" не может быть общим для всех, у каждого окна свой набор объектов (иногда всего 1 объект)Приведу пример для предложенного мной решения: допустим, есть окно, отображающее графический файл. Файл загружается по сети долго. Сервер обновляет данный файл. Пользователь нажимает кнопку "обновить". Команда идет в контейнер, тот выбрасывает сигнал updating(). Окно сразу же стирается и пишется "Loading... 0%". Далее по мере загрузки контейнер периодически бросает сигнал duringUpdate(). Соответственно в окне "Loading... 1%" и т.д. Когда файл будет загружен, контейнер бросает сигнал updated(), и окно отображает файл. Ну это ситуация простая - сначала все загрузили - потом все отрисовали. Моя же задача "исключить" из рисования невалидный объектНазвание: Re: Временно блокировать рисование объекта Отправлено: Akon от Сентябрь 30, 2010, 22:38 Есть объект. В плане рисования оъект или готов или не готов. При рисовании если хотя бы один из объектов не готов, то:
1) не рисуется ничего (Loading x%); 2) рисуются только готовые объекты. Я привел свой вариант на п.1. Если п.2, то мне не понятно в чем проблема - ну исключил неготовые и отрисовал? Или проблема в самом алгоритме исключения? Название: Re: Временно блокировать рисование объекта Отправлено: Alex_cs_gsp от Сентябрь 30, 2010, 22:45 А через фильтр сообщений не получится? Каким образои?Отлавливать paintEvent() и проверять любимый флаг. Название: Re: Временно блокировать рисование объекта Отправлено: Igors от Сентябрь 30, 2010, 22:50 то мне не понятно в чем проблема - ну исключил неготовые и отрисовал? Или проблема в самом алгоритме исключения? А каким образом "исключил"? См. пост #13 по поводу того какие проблемы я имеюОтлавливать paintEvent() и проверять любимый флаг. А есть ли еще идеи кроме проверки флажка?Название: Re: Временно блокировать рисование объекта Отправлено: Alex_cs_gsp от Сентябрь 30, 2010, 22:53 Так все-равно, если есть что-то "встроенное", то там также флаг проверяется.
Название: Re: Временно блокировать рисование объекта Отправлено: Akon от Сентябрь 30, 2010, 23:07 Цитировать А каким образом "исключил"? См. пост #13 по поводу того какие проблемы я имею Т.е. проблема в механизме исключения? Тогда рисование (PaintEvent'ы и т.п.) это отдельная (тривиальная) задача и пох. сколько там окон. Название: Re: Временно блокировать рисование объекта Отправлено: Igors от Сентябрь 30, 2010, 23:35 Т.е. проблема в механизме исключения? Да. Проверку на созданный флажок придется втыкивать в очень многие места, а если появятся новые - опять тыкать. И нельзя сказать "ну это неизбежно" - ведь способ исключения уже есть (см. пост #5) |