Russian Qt Forum

Qt => Общие вопросы => Тема начата: bigirbis от Август 01, 2007, 17:05



Название: Перерисовка виджета по необходимости
Отправлено: bigirbis от Август 01, 2007, 17:05
Перерисовка контента моего виджета отнимает много ресурсов.
Таких виджетов может быть десятки в QScrollArea.

Можно ли из этого виджета узнать, не закрыт ли он чем либо, дабы лишний раз не перерисовывать? Есть ли какие-нибудь валидные ходы?


Название: Перерисовка виджета по необходимости
Отправлено: pakulo от Август 01, 2007, 20:19
Можно узнать, найти все виджеты у которых батька один (т.е. все виджеты в твоем QScrollArea), а потом проверять не закрыт ли или есть ли он на экране в данный момент. Проверить можно так. Получаешь QRect geometry() каждого виджета и через bool contains ( const QRect & rectangle, bool proper = false ) const  проверяешь не находиться ли в нем какой-нить виджет или наоборот не находиться ли этот в каком-то (т.е. закрывается) и все...
Если я не ошибаюсь, то получить список всех виджетов так QList<T> QObject::findChildren ( const QString & name = QString() ) const
Т.е. пишешь в
void paintEvent( QPaintEvent * event )
{
...
QList<QWidget *> widgets = parent().findChildren<QWidget *>();
for (int i = 0; i < widgets.count(); ++i)
{
if (widgets.geometry().contains(geometry()))
{
кто-то закрыл, не рисовать
}
else
никто не закрыл, или частично закрыл
}
}

вроде что-то типа того

Можно еще проверять какая часть закрыта, если частично закрыто


Название: Перерисовка виджета по необходимости
Отправлено: pastor от Август 01, 2007, 23:19
Смотрим в сторону QPaintEvent::rect ()
Цитировать

Returns the rectangle that needs to be updated.


или QPaintEvent::region ()

Цитировать

Returns the region that needs to be updated.


Полученый регион перерисовываем. оно?


Название: Перерисовка виджета по необходимости
Отправлено: pakulo от Август 02, 2007, 08:30
Не, не оно... это нужно для того, что бы проверить какую область запросили перерисовать... Т.е. если я где-то писал update(QRect()) то оно возовет paintEvent и передаст в QPaintEvent::rect () нужные координаты... И ты тогда можешь вызывать и делать только то, что нужно для конкретно этой области... В даном случае нужно узнать накрыт ли виджет чем-то... Кстати, QPaintEvent::rect (), тоже очень полезная штука, если у тебя есть где-то update(QRect()) update(QRegion()), то советую посмотреть...


Название: Re: Перерисовка виджета по необходимости
Отправлено: Gryz от Август 02, 2007, 23:30
Цитата: "bigirbis"
Таких виджетов может быть десятки в QScrollArea.


QScrollArea посылает QPaintEvent только видимым виджетам.


Название: Re: Перерисовка виджета по необходимости
Отправлено: pakulo от Август 02, 2007, 23:39
Цитата: "Gryz"
Цитата: "bigirbis"
Таких виджетов может быть десятки в QScrollArea.


QScrollArea посылает QPaintEvent только видимым виджетам.

Если я правильно понял, то ему нужно если виджет накрыт другим виджетом.


Название: Перерисовка виджета по необходимости
Отправлено: bigirbis от Август 03, 2007, 17:02
Цитировать
Если я правильно понял, то ему нужно если виджет накрыт другим виджетом.

Именно так.


Название: Перерисовка виджета по необходимости
Отправлено: pakulo от Август 03, 2007, 21:18
Цитата: "bigirbis"
Цитировать
Если я правильно понял, то ему нужно если виджет накрыт другим виджетом.

Именно так.

Попробуй разобраться с тем, что я написал... Другого варианта я не вижу


Название: Перерисовка виджета по необходимости
Отправлено: Sergeich от Август 03, 2007, 22:29
дык вроде в четверке по умолчанию юзается двойная буферизация, или ты тройку юзаешь?


Название: Перерисовка виджета по необходимости
Отправлено: pakulo от Август 03, 2007, 23:58
Цитата: "Sergeich"
дык вроде в четверке по умолчанию юзается двойная буферизация, или ты тройку юзаешь?

Проблема не в выводе, наверное, а в самой функции которая выводит на экран содержимое виджета. Т.е. если я правильно понял, ему нужно узнать если виджет чем-то накрыт, то не делать операции которые отвечают за вывод виджета на экран, поскольку они занимают много ресурсов. Т.е. например при изминении размеров окна, у него наверное все тормозит ибо много виджетов и все вызывают функции для прорисовки виджета, т.е. что-то наверное большое щитают :)
А вообще КуТе сам узнает, накрыт не накрыт и тогда уже на экран выводит только то что нужно. Но он не может узнать, производить какие-то действия которые прорисовывают виджет или нет, это нужно самому делать, т.е. ты в paintEvent написал там нарисовать 1000 линий, будет вызвано 1000 методов для прорисовки линий, но на экране КуТе покажет только то что нужно. А тут нужно просчитать, если какая-то часть виджета накрыта, то вызывать не 1000 методов для прорисовки линий, а 10, что существенно увеличит производительность :)


Название: Перерисовка виджета по необходимости
Отправлено: Gryz от Август 04, 2007, 00:05
Двойная буферизация тут не причем. Она необходима для избежания мерцания при отрисовке.

Требуется тратить поменьше времени на отрисовку каждого сложного виджета.
Только что проверил: QPaintEvent::region () содержит список прямоугольников, которые являются видимыми частями виджета.

Надо просто грамотно реализовать paintEvent.

Т.е. делать то, что писал pakulo, необязательно.
Проверял на наследнике QFrame, один экземпляр которого перекрывал другой экземпяр. Оба расположены на виджете. Qt 4.3.0.