Russian Qt Forum
Ноябрь 24, 2024, 20:36
Добро пожаловать,
Гость
. Пожалуйста,
войдите
или
зарегистрируйтесь
.
Вам не пришло
письмо с кодом активации?
1 час
1 день
1 неделя
1 месяц
Навсегда
Войти
Начало
Форум
WIKI (Вики)
FAQ
Помощь
Поиск
Войти
Регистрация
Russian Qt Forum
>
Forum
>
Qt
>
2D и 3D графика
>
[РЕШЕНО] Отрисовка части изображения в QPaintEvent при изменении размера окна
Страниц: [
1
]
2
Вниз
« предыдущая тема
следующая тема »
Печать
Автор
Тема: [РЕШЕНО] Отрисовка части изображения в QPaintEvent при изменении размера окна (Прочитано 13933 раз)
marbius
Гость
[РЕШЕНО] Отрисовка части изображения в QPaintEvent при изменении размера окна
«
:
Апрель 25, 2010, 10:27 »
Доброго времени суток.
Совершенно случайно наткнулся на такую неприятную (при большом количестве выводимых объектов) "особенность":
при изменении размеров окна, на котором происходит отрисовка через QPaintEvent,
paintRect
QPaintEvent::rect () ВСЕГДА возвращает координаты верхнего левого угла для перерисовки как (0;0) - т.е. контент перерысовывается полностью.
Возможно ли как-то изменить ситуацию так, чтобы, например, при изменении размера окна по вертикали по rect() возвращалась только недостающая нижняя часть окна, действительно необходимая для "дорисовки"?
Спасибо.
«
Последнее редактирование: Апрель 26, 2010, 16:14 от marbius
»
Записан
alexman
Гость
Re: Отрисовка части изображения в QPaintEvent при изменении размера окна
«
Ответ #1 :
Апрель 25, 2010, 10:34 »
Используй void QWidget::resizeEvent( QResizeEvent * event ). А в QResizeEvent можно использовать для анализа методы const QSize & oldSize () const, const QSize & size () const.
Записан
alexman
Гость
Re: Отрисовка части изображения в QPaintEvent при изменении размера окна
«
Ответ #2 :
Апрель 25, 2010, 10:39 »
А const QRect & QPaintEvent::rect () const всегда возвращает всю область?
Записан
marbius
Гость
Re: Отрисовка части изображения в QPaintEvent при изменении размера окна
«
Ответ #3 :
Апрель 25, 2010, 11:05 »
Цитата: alexman от Апрель 25, 2010, 10:34
Используй void QWidget::resizeEvent( QResizeEvent * event ). А в QResizeEvent можно использовать для анализа методы const QSize & oldSize () const, const QSize & size () const.
Как тогда можно убрать из очереди отрисовку всей области, попадающую в QPaintEvent после изменения размеров окна?
Получается, что область перерисовывается трижды: дважды я инициирую дорисовку "справа" и "снизу", а затем идет обычное сообщение опять-таки на обновление всей области. (введение флагов не помогло)
Цитата: alexman от Апрель 25, 2010, 10:39
А const QRect & QPaintEvent::rect () const всегда возвращает всю область?
Не совсем понял вопроса. Я писал, что при изменении размеров окна
paintRect
rect() возвращает всю область, от (0;0) по (width;height).
«
Последнее редактирование: Апрель 25, 2010, 15:09 от marbius
»
Записан
alexman
Гость
Re: Отрисовка части изображения в QPaintEvent при изменении размера окна
«
Ответ #4 :
Апрель 25, 2010, 11:50 »
Цитата: marbius от Апрель 25, 2010, 11:05
Цитата: alexman от Апрель 25, 2010, 10:34
Используй void QWidget::resizeEvent( QResizeEvent * event ). А в QResizeEvent можно использовать для анализа методы const QSize & oldSize () const, const QSize & size () const.
Как тогда можно убрать из очереди отрисовку всей области, попадающую в QPaintEvent после изменения размеров окна?
Получается, что область перерисовывается трижды: дважды я инициирую дорисовку "сверху" и "снизу", а затем идет обычное сообщение опять-таки на обновление всей области. (введение флагов не помогло)
void QWidget::paintEvent ( QPaintEvent * event ) тоже переопредели!
Цитата: marbius от Апрель 25, 2010, 11:05
Цитата: alexman от Апрель 25, 2010, 10:39
А const QRect & QPaintEvent::rect () const всегда возвращает всю область?
Не совсем понял вопроса. Я писал, что при изменении размеров окна paintRect возвращает всю область, от (0;0) по (width;height).
Написано же про rect! Метод paintRect даже не нашел!
Записан
marbius
Гость
Re: Отрисовка части изображения в QPaintEvent при изменении размера окна
«
Ответ #5 :
Апрель 25, 2010, 12:04 »
Цитировать
void QWidget::paintEvent ( QPaintEvent * event ) тоже переопредели!
Цитировать
Написано же про rect! Метод paintRect даже не нашел!
Извини, но непродуктивный "разговор": кто-то кого-то не понимает, скорее всего, я.
если я "рисую" самостоятельно, то, скорее всего, метод у меня и так переопределен. вопрос в том, что перерисовка при изменении размеров попадает в очередь, и соответственно в обработчик события, помимо моей воли, так сказать из недр qt. Вопрос сейчас в том, как это можно предотвратить. Я подозреваю, что это происходит из-за перерисовки фона, но могу и ошибаться.
А paintRect - это не метод, это просто моя опечатка. Увы, но разговор шел именно про const QRect & QPaintEvent::rect () const и именно этот метод возвращает нули...
Записан
alexman
Гость
Re: Отрисовка части изображения в QPaintEvent при изменении размера окна
«
Ответ #6 :
Апрель 25, 2010, 12:10 »
Еще можно использовать флаг Qt::WA_OpaquePaintEvent.
Записан
marbius
Гость
Re: Отрисовка части изображения в QPaintEvent при изменении размера окна
«
Ответ #7 :
Апрель 25, 2010, 12:24 »
Цитата: alexman от Апрель 25, 2010, 12:10
Еще можно использовать флаг Qt::WA_OpaquePaintEvent.
Увы, все те же (0;0) только теперь уже без фона
Скорее всего придется смириться с медленной отрисовкой.... Но, все же как-то же это должно решаться...
alexman, спасибо за потраченное время.
Вопрос открыт.
Записан
alexman
Гость
Re: Отрисовка части изображения в QPaintEvent при изменении размера окна
«
Ответ #8 :
Апрель 25, 2010, 13:33 »
1. Хранить текущий rect и предыдущий rect (оба в глобальных координатах).
2. В void QWidget::resizeEvent ( QResizeEvent * event ), void QWidget::moveEvent ( QMoveEvent * event ) rect-ы пересчитываются.
3. В void QWidget::paintEvent ( QPaintEvent * event ) рисовка (по обоим rect-ам можно проанализировать, что перерисовывать).
4. QPoint QWidget::mapToGlobal ( const QPoint & pos ) const - получинение глобальных координат.
Записан
marbius
Гость
Re: Отрисовка части изображения в QPaintEvent при изменении размера окна
«
Ответ #9 :
Апрель 25, 2010, 13:51 »
Цитата: alexman от Апрель 25, 2010, 13:33
1. Хранить текущий rect и предыдущий rect (оба в глобальных координатах).
2. В void QWidget::resizeEvent ( QResizeEvent * event ), void QWidget::moveEvent ( QMoveEvent * event ) rect-ы пересчитываются.
3. В void QWidget::paintEvent ( QPaintEvent * event ) рисовка (по обоим rect-ам можно проанализировать, что перерисовывать).
4. QPoint QWidget::mapToGlobal ( const QPoint & pos ) const - получинение глобальных координат.
Спасибо за ответ, но соль в том, что:
а) если "не извращаться", то потом при выходе из QWidget::resizeEvent, в очереди все мои попытки отрисовать свои прямоугольники "съедаются" глобальной перерисовкой с координатами (0;0; width*height);
б) если "поизвращаться" и ввести разного рода флаги-блокировки, то получается, что контент будет отрисовываться трижды, как я уже писАл, причем самое печальное, что опять-таки последней будет глобальная перерисовка.
Возможный вариант решения, как всегда прост и уже неоднократно описан: использовать QPixmap, и при QWidget::paintEvent выводить только его, а уже при QWidget::resizeEvent расчитывать свои прямоугольники и выводить на QPixmap. Все же думал, что есть более "прямое" решение.
Записан
alexman
Гость
Re: Отрисовка части изображения в QPaintEvent при изменении размера окна
«
Ответ #10 :
Апрель 25, 2010, 13:56 »
Цитата: marbius от Апрель 25, 2010, 13:51
Возможный вариант решения, как всегда прост и уже неоднократно описан: использовать QPixmap, и при QWidget::paintEvent выводить только его, а уже при QWidget::resizeEvent расчитывать свои прямоугольники и выводить на QPixmap. Все же думал, что есть более "прямое" решение.
Да, это быстро работает! Проверенно много раз!
Записан
marbius
Гость
Re: Отрисовка части изображения в QPaintEvent при изменении размера окна
«
Ответ #11 :
Апрель 25, 2010, 14:07 »
Цитата: alexman от Апрель 25, 2010, 13:56
Да, это быстро работает! Проверенно много раз!
Offtopic
Но это лишние затраты памяти. И к тому же насколько я понял, в Qt и так используется буферизация вывода, а так получается, что еще один дополнительный буфер. Вот это меня смущает при использовании QPixmap. Поправьте меня, если я ошибаюсь.
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Отрисовка части изображения в QPaintEvent при изменении размера окна
«
Ответ #12 :
Апрель 25, 2010, 14:44 »
1) Какую область (region, rectangle) нужно перерисовывать - занимается ОС. Не видно оснований почему при resize нужно "инвалидировать" только часть - в большинстве случаев окно должно быть полностью обновлено если его размер изменился
2) Кто буферирует - дело темное (платформо-зависимое). Напр. на Mac это сам OC
3) QPixmap - верная дорога. Опасения по поводу расходов на буфер беспочвенны. Прикинем: окно 1024 х 1024, расход памяти 4 Мб. Это по нынешним временам не объем. Для сравнения если Вы масштабируете картинку в несколько раз - очень быстро расходы превышают 100 Мб, но я еще не видел попыток сэкономить память на этом
Записан
marbius
Гость
Re: Отрисовка части изображения в QPaintEvent при изменении размера окна
«
Ответ #13 :
Апрель 25, 2010, 15:03 »
Цитата: Igors от Апрель 25, 2010, 14:44
... Не видно оснований почему при resize нужно "инвалидировать" только часть - в большинстве случаев окно должно быть полностью обновлено если его размер изменился...
Ну, я могу возразить (опять-таки частный случай): я тяну окошко за нижнюю границу, у меня невалидная только та часть, которая появляется снизу.
Или вот более худший вариант: есть QWidget - главное окно, в котором находится еще один QWidget - мой виджет, допустим размером 100х100 пикселей, причем для главного окна я установил setMinimumSize (200, 200); я меняю размеры главного окна (тяну мышью, например). Зачем мне перерисовывать дочерний виджет каждый раз при изменении размеров главного окна? (возможно, этот вариант больше offtopic и суть другой темы, но все же имеет место быть).
Чтож, QPixmap - все же более верное и быстрое решение, чем копаться в недрах qt.
Принимаю последнее как решение проблемы.
Записан
GreatSnake
Джедай : наставник для всех
Offline
Сообщений: 2921
Re: Отрисовка части изображения в QPaintEvent при изменении размера окна
«
Ответ #14 :
Апрель 26, 2010, 09:54 »
Qt::WA_StaticContents
Записан
Qt 5.11/4.8.7 (X11/Win)
Страниц: [
1
]
2
Вверх
Печать
« предыдущая тема
следующая тема »
Перейти в:
Пожалуйста, выберите назначение:
-----------------------------
Qt
-----------------------------
=> Вопросы новичков
=> Уроки и статьи
=> Установка, сборка, отладка, тестирование
=> Общие вопросы
=> Пользовательский интерфейс (GUI)
=> Qt Quick
=> Model-View (MV)
=> Базы данных
=> Работа с сетью
=> Многопоточное программирование, процессы
=> Мультимедиа
=> 2D и 3D графика
=> OpenGL
=> Печать
=> Интернационализация, локализация
=> QSS
=> XML
=> Qt Script, QtWebKit
=> ActiveX
=> Qt Embedded
=> Дополнительные компоненты
=> Кладовая готовых решений
=> Вклад сообщества в Qt
=> Qt-инструментарий
-----------------------------
Программирование
-----------------------------
=> Общий
=> С/C++
=> Python
=> Алгоритмы
=> Базы данных
=> Разработка игр
-----------------------------
Компиляторы и платформы
-----------------------------
=> Linux
=> Windows
=> Mac OS X
=> Компиляторы
===> Visual C++
-----------------------------
Разное
-----------------------------
=> Новости
===> Новости Qt сообщества
===> Новости IT сферы
=> Говорилка
=> Юмор
=> Объявления
Загружается...