Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: izoomer от Январь 19, 2007, 00:13



Название: тормозит QPainter у QWidget
Отправлено: izoomer от Январь 19, 2007, 00:13
Код:

void MainWindow::paintEvent(QPaintEvent *  /*event*/ )
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);
    QRect BackgroundRect(0, 0, 800,600);
    painter.setBrush(QBrush(Qt::black, Qt::SolidPattern));
    painter.drawRect( BackgroundRect );
}


если включена опция антиалиасинга
Код:

    painter.setRenderHint(QPainter::Antialiasing, true);

то тормозит все что на виджетет этом находится, другие виджеты ему принадлежащие, например списки медленно прокручиваются. Если этой строки нет - то все ОК. А нужно еще рисовать много чего по виджету , думаю совсем будет нереально тормозить. Чего надо сделать что бы все было как надо ?


Название: тормозит QPainter у QWidget
Отправлено: Dendy от Январь 19, 2007, 00:33
Какая ОС? Железо? Тормозит в дебаге или рилизе?


Название: тормозит QPainter у QWidget
Отправлено: Alex03 от Январь 19, 2007, 08:09
ИМХО для перерисовки больших объектов у/на которых куча чилдов, не плохо на QPaintEvent объект глядеть. Может Вам приходит сотня паинтевентов на небольшие кусочки окна, а Вы при этом всё окно перерисовываете.
Ещё я не понимаю зачем Antialiasing при заливке солидом?


Название: тормозит QPainter у QWidget
Отправлено: izoomer от Январь 19, 2007, 20:24
Цитировать

Какая ОС? Железо? Тормозит в дебаге или рилизе?

Linux . Встроеная видюха на матери. Тормозит в релизе, но не думаю что это может влиять.
Цитировать

ИМХО для перерисовки больших объектов у/на которых куча чилдов, не плохо на QPaintEvent объект глядеть. Может Вам приходит сотня паинтевентов на небольшие кусочки окна, а Вы при этом всё окно перерисовываете.
Ещё я не понимаю зачем Antialiasing при заливке солидом?

Это только один из объектов рисованых, остальные нужно с антиалиасом рисовать, без него никак.
Можно развернуть ответ по поводу PaintEvent объекта ?

добавлено спустя 34 минуты:

 попробывал - тормозит как на релизе так и на дебаге.


Название: тормозит QPainter у QWidget
Отправлено: Dendy от Январь 19, 2007, 20:48
На линуксе может сильно тормозить при отсутствии расширения иксов XRender.


Название: тормозит QPainter у QWidget
Отправлено: izoomer от Январь 19, 2007, 20:52
компилится проект qt с ключем -lXrender


Название: тормозит QPainter у QWidget
Отправлено: izoomer от Январь 20, 2007, 15:15
Xrender в системе установлен
что же может быть ? как ускорить ? подскажите знающие


Название: тормозит QPainter у QWidget
Отправлено: fanat9 от Январь 21, 2007, 17:44
ЧТо за видюха и какие драйвера используеются ?


Название: тормозит QPainter у QWidget
Отправлено: izoomer от Январь 22, 2007, 14:51
на данный момент видик Radeon 9550 дрова станартные - модуль radeon


Название: тормозит QPainter у QWidget
Отправлено: Alex03 от Январь 22, 2007, 16:05
Цитата: "izoomer"

Можно развернуть ответ по поводу PaintEvent объекта ?

Ну там ж всё неписано.
Цитировать
The QPaintEvent class contains event parameters for paint events.

Paint events are sent to widgets that need to update themselves, for instance when part of a widget is exposed because a covering widget was moved.

The event contains a region() that needs to be updated, and a rect() that is the bounding rectangle of that region. Both are provided because many widgets can't make much use of region(), and rect() can be much faster than region().boundingRect(). Painting is clipped to region() during the processing of a paint event.


Т.е. Вас могут попросить перерисовать один пиксел, а Вы перерисовываете всё.
Например если на Вашем окне лежит одно другое прямоугольное окно (например кнопка),  к Вам может прийти 4 paintEvent-а для перерисовки всего окна. И т.д.
И если другие объекты (как то линии и т.д.) рисовать не очень клёва только для текущего прямоугольника из QPaintEvent-а, то уж фон то чистить надо всяко по этому rect-у.


Название: тормозит QPainter у QWidget
Отправлено: izoomer от Январь 23, 2007, 11:31
а как это все выгдлядит в коде ?


Название: тормозит QPainter у QWidget
Отправлено: Alex03 от Январь 23, 2007, 13:37
Цитата: "izoomer"
а как это все выгдлядит в коде ?

Для Вашего примера
Код:
void MainWindow::paintEvent(QPaintEvent *  /*event*/ ) 
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);
    QRect BackgroundRect(0, 0, 800,600);
    painter.setBrush(QBrush(Qt::black, Qt::SolidPattern));
    painter.drawRect( BackgroundRect );
}

Например так:
Код:
void MainWindow::paintEvent(QPaintEvent *  event ) 
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);
    QRect BackgroundRect = event->rect();
    painter.setBrush(QBrush(Qt::black, Qt::SolidPattern));
    painter.drawRect( BackgroundRect );
}


Ну или просто попробуйте для начала просто попечатать event->rect() в консоль.

Ну а если ещё чего там рисуется то:
Код:
void MainWindow::paintEvent(QPaintEvent *  event ) 
{
    QPainter painter(this);
    QRect BackgroundRect = event->rect();
    painter.setBrush(QBrush(Qt::black, Qt::SolidPattern));
    painter.drawRect( BackgroundRect );

    painter.setRenderHint(QPainter::Antialiasing, true);
    ...
    // а тут желательно рисовать в пределах BackgroundRect
}


добавлено спустя 7 минут:

 Кстати может ещё
Код:
painter.setClipRegion(event->region());

поможет?


Название: тормозит QPainter у QWidget
Отправлено: izoomer от Январь 23, 2007, 18:14
ну так в этом случае все пройдет если нарисован один черный квадрат.
В моем случае ещё есть
Код:

    painter.setBrush(QBrush(Qt::red, Qt::SolidPattern));
    painter.drawRoundRect( MainRect, 3, 3);


да плюс ещё это квадрат градиентную заливку имеет

Как в это случае быть ?
Может можно как то по другому на фоне рисовать различные вещи с антиалиасом ?


Название: тормозит QPainter у QWidget
Отправлено: Alex03 от Январь 24, 2007, 08:36
Если картинка статичная то двойная буферизация тоже рулит.


Название: тормозит QPainter у QWidget
Отправлено: izoomer от Январь 24, 2007, 17:50
нашел только
Код:

void QGLFormat::setDoubleBuffer ( bool enable )

но это для OpenGL виджета ... а у меня простой QWidget, да и двойная буферизация включена по умолчанию.
Или я что то не так понял ? можно пример для понимания ?


Название: тормозит QPainter у QWidget
Отправлено: Alex03 от Январь 25, 2007, 12:12
Вручную на примере 3.х.х
Добовляете в свой MainWindow
QPixmap bgPixmap;
Во время инициализации, и при ресайзинге окна рисуете в этом bgPixmap всё что душе угодно с любыми антиалиасингами и т.д.
Ну а Ваш paintEvent() Заменяете на чтото типа:
Код:

void MainWindow::paintEvent(QPaintEvent *  event )
{
    QPainter painter(this);
    QRect r = event->rect();
    painter.drawPixmap(r.topLeft(), bgPixmap, r);
}


Название: тормозит QPainter у QWidget
Отправлено: chezz от Март 11, 2007, 05:08
Цитата: "Alex03"
Вручную на примере 3.х.х
Добовляете в свой MainWindow
QPixmap bgPixmap;
Во время инициализации, и при ресайзинге окна рисуете в этом bgPixmap всё что душе угодно с любыми антиалиасингами и т.д.
Ну а Ваш paintEvent() Заменяете на чтото типа:
Код:

void MainWindow::paintEvent(QPaintEvent *  event )
{
    QPainter painter(this);
    QRect r = event->rect();
    painter.drawPixmap(r.topLeft(), bgPixmap, r);
}


Хмм. Имею вот такой кусок кода:
Код:
void TestWidget::paintEvent(QPaintEvent * paintEvent)
{
QPainter painter(this);
draw();
painter.drawPixmap(paintEvent->rect(), bufferPixmap);
painter.end();
}

void TestWidget::draw()
{
bufferPixmap = QPixmap(size());
bufferPixmap.fill(Qt::transparent);
QPainter painter(&bufferPixmap);
painter.setRenderHint(QPainter::Antialiasing, true);
QPolygon polyline;
const int N = 40;
for(int i = 0; i < N; i++)
{
polyline.append(QPoint(i*width()/N, height()*(i%2)));
}
painter.setPen(QPen(Qt::black, 1, Qt::SolidLine));
painter.drawPolyline(polyline);
}

то есть отрисовка ломаной из 40 линий, геометрия которой задается размерами виджета.
Без антиалиасинга работает ...ну достаточно быстро. С антиалиасингом - жуткие тормоза. Ресайзинг жду секунду/полторы.
Железо - 640 оперативы, ~1900 проц, видюха - geforce4 MX 64Mb
(да и на компе помощнее на работе такой же результат)
Qt 4.2.2 коммерческий.
Кто-нить знает почему так? То есть это баг или фича?
Я вот держу в руках QWT-5 и смотрю на примеры типа realtime_plot, data_plot и cpuplot. Последний с антиалиасингом при таймере на 50 мс летает при резайсинге (то есть перерисовка с нуля выполняется быстро). У меня же все тупит в более элементарном случае.
Может кто подскажет, какие такие хитрости используются в QWT (которые я может упустил, когда пробегал исходники) ?


Название: тормозит QPainter у QWidget
Отправлено: Alex03 от Март 11, 2007, 10:26
Не надо draw() вызывать из paintEvent()-а
Вызывайте draw() только при:
- инициализации
- ресайзинге
- Изменении содержимого.

Плюс для TestWidget выключите очистку фона (если этого не сделано)


Название: тормозит QPainter у QWidget
Отправлено: chezz от Март 12, 2007, 03:33
Цитата: "Alex03"
Не надо draw() вызывать из paintEvent()-а
Вызывайте draw() только при:
- инициализации
- ресайзинге
- Изменении содержимого.

Плюс для TestWidget выключите очистку фона (если этого не сделано)

Ну это уже некоторое буквоедство... Понятно, что писать так грамотней, но это не изменяет сути проблемы.
Факт на лицо: антиалиасинг выключен - всё относительно быстро рисуется, включен - тормозит. Думаю, что это явно локализует проблемное место - антиалиасинг, а не неуместный вызов draw() (да и потом переделал уже код и вызываю draw() там где надо - эффект тот же...)

Так что вопрос остается открытым:
Есть факт, указывающий на антиалиасинг как причину тормозов.
Вопрос - это баг и стоит надеяться на лучшее? Или же это фича и стоит смириться и искать альтернативу?..
Вообще ведь тот же cpuplot из qwt при ресайзинге ведет себя очень шустро, а там антиалиасинг и куча кривых, заливок и т.п.
Так что все же было бы интересно услышать некоторые комментарии по QWT - можт кто глубже копал исходники или просто знает методы быстрого рисования QPainter'ом по QWidget'у?


Название: тормозит QPainter у QWidget
Отправлено: Alex03 от Март 12, 2007, 14:09
А встроенная видюха имеет свой иксовый драйвер, или какойнить универсальный пользует?


Название: тормозит QPainter у QWidget
Отправлено: chezz от Март 12, 2007, 15:09
А кто сказал, что она встроенная? :?
Обычная видюха, драйвер с дисочка. Да и потом думаю и она здесь ни при чем - ведь примерчик cpuplot из qwt летает на ура, на той же видюхе... Значит видимо проблема в коде. Неужели qwt как-то по-другому рисует (не как я через QPixmap) и при этом получается гораздо быстрее? Проще, чем у меня, я придумать не могу...