Russian Qt Forum
Ноябрь 24, 2024, 21:03 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Перерисовка виджета по необходимости  (Прочитано 7062 раз)
bigirbis
Гость
« : Август 01, 2007, 17:05 »

Перерисовка контента моего виджета отнимает много ресурсов.
Таких виджетов может быть десятки в QScrollArea.

Можно ли из этого виджета узнать, не закрыт ли он чем либо, дабы лишний раз не перерисовывать? Есть ли какие-нибудь валидные ходы?
Записан
pakulo
Гость
« Ответ #1 : Август 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
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #2 : Август 01, 2007, 23:19 »

Смотрим в сторону QPaintEvent::rect ()
Цитировать

Returns the rectangle that needs to be updated.


или QPaintEvent::region ()

Цитировать

Returns the region that needs to be updated.


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

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
pakulo
Гость
« Ответ #3 : Август 02, 2007, 08:30 »

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

Цитата: "bigirbis"
Таких виджетов может быть десятки в QScrollArea.


QScrollArea посылает QPaintEvent только видимым виджетам.
Записан
pakulo
Гость
« Ответ #5 : Август 02, 2007, 23:39 »

Цитата: "Gryz"
Цитата: "bigirbis"
Таких виджетов может быть десятки в QScrollArea.


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

Если я правильно понял, то ему нужно если виджет накрыт другим виджетом.
Записан
bigirbis
Гость
« Ответ #6 : Август 03, 2007, 17:02 »

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

Именно так.
Записан
pakulo
Гость
« Ответ #7 : Август 03, 2007, 21:18 »

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

Именно так.

Попробуй разобраться с тем, что я написал... Другого варианта я не вижу
Записан
Sergeich
Гость
« Ответ #8 : Август 03, 2007, 22:29 »

дык вроде в четверке по умолчанию юзается двойная буферизация, или ты тройку юзаешь?
Записан
pakulo
Гость
« Ответ #9 : Август 03, 2007, 23:58 »

Цитата: "Sergeich"
дык вроде в четверке по умолчанию юзается двойная буферизация, или ты тройку юзаешь?

Проблема не в выводе, наверное, а в самой функции которая выводит на экран содержимое виджета. Т.е. если я правильно понял, ему нужно узнать если виджет чем-то накрыт, то не делать операции которые отвечают за вывод виджета на экран, поскольку они занимают много ресурсов. Т.е. например при изминении размеров окна, у него наверное все тормозит ибо много виджетов и все вызывают функции для прорисовки виджета, т.е. что-то наверное большое щитают Улыбающийся
А вообще КуТе сам узнает, накрыт не накрыт и тогда уже на экран выводит только то что нужно. Но он не может узнать, производить какие-то действия которые прорисовывают виджет или нет, это нужно самому делать, т.е. ты в paintEvent написал там нарисовать 1000 линий, будет вызвано 1000 методов для прорисовки линий, но на экране КуТе покажет только то что нужно. А тут нужно просчитать, если какая-то часть виджета накрыта, то вызывать не 1000 методов для прорисовки линий, а 10, что существенно увеличит производительность Улыбающийся
Записан
Gryz
Гость
« Ответ #10 : Август 04, 2007, 00:05 »

Двойная буферизация тут не причем. Она необходима для избежания мерцания при отрисовке.

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

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

Т.е. делать то, что писал pakulo, необязательно.
Проверял на наследнике QFrame, один экземпляр которого перекрывал другой экземпяр. Оба расположены на виджете. Qt 4.3.0.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.076 секунд. Запросов: 22.