Название: оптимизация paint() QGraphicsItem'а Отправлено: AlexeyChe от Март 18, 2011, 12:12 Доброго дня!
Ковыряюсь уже давно, но к сожалению не хватает опыта. Задача нарисовать систему координат +прочие простые элементы, типа квадратиков кружочков, которых может быть не малое количество. в основе граф.части лежит класс PolarPlot наследованный от QGraphicsView, в конструкторе которого создаётся scene Код: plotScene=new QGraphicsScene(0,0,700,700); после чего добавляется система координат в виде объекта класса PolarAxis наследованного от QGraphicsItem Код: pa = new PolarAxis(350,350,300,cRotate); в PolarAxis перегружен метод paint в котором и происходит всё рисование, не буду вдаваться в подробности рисования, ибо оно проходит нормально, да и ничего сложного там нет. Всё работает, но очень медленно, дебаггер говорит что тот самый метод paint вызывается огромное количество раз, загружая систему под максимум. Про resizeEvent и написанный там scale, и нечего говорить, работает, но медленно. Погуглил. Нашел Double Buffering. Я может толком его не понял, но пытаюсь сделать таким образом: всё рисование идет в Pixmap, созданный здесь(конструктор PolarPlot): Код: pa = new PolarAxis(350,350,300,cRotate); рисование осуществил в методе класса PolarAxis drawToBuff(), в котором создается и закрывается QPainter таким образом Код: QPainter *p=new QPainter(pm); //pm - адрес того самого Pixmap'a в PolarAxis::paint() Код: if(!drawOk) drawToBuff(); //читай: если не нарисовано - рисуй! итого, рисуется просто черный квадрат я наверно не правильно использую Pixmap, и рисование в него. +многопоточность! я не понимаю саму структуру как мне создать отдельный поток для рисования, посмотрел забугорные примеры, в основном, рисование идет прямо в классе наследованном от QThread, просто процедурой. Единственный ли это способ? хотелось бы сохранить структуру классов адекватной, чтобы рисование было возложено на объекты класса графических элементов. буду благодарен за помощь Название: Re: оптимизация paint() QGraphicsItem'а Отправлено: GreatSnake от Март 18, 2011, 12:19 Цитировать в PolarAxis перегружен метод paint в котором и происходит всё рисование, не буду вдаваться в подробности рисования, ибо оно проходит нормально, да и ничего сложного там нет. Получается что сей класс помимо осей отрисовывает "простые элементы, типа квадратиков кружочков, которых может быть не малое количество". ?Название: Re: оптимизация paint() QGraphicsItem'а Отправлено: AlexeyChe от Март 18, 2011, 13:43 Получается что сей класс помимо осей отрисовывает "простые элементы, типа квадратиков кружочков, которых может быть не малое количество". ? Нет, этот класс рисует только осьв будущем планируется помимо осей добавлять на сцену самостоятельные объекты классов, наследованных от QGraphicsItem, аналогичных PolarAxis Мне бы хотя бы оси нормально нарисовать элементы типа квадратиков кружочков я упомянул здесь только для того чтобы показать как необходима адекватная оптимизация Название: Re: оптимизация paint() QGraphicsItem'а Отправлено: GreatSnake от Март 18, 2011, 13:48 Пока не покажешь как отрисовываешь элементы и как масштабируешь сцену никто тебе не поможет.
Но, то что сам пытаешься реализовать double-buffering, не решив проблемы с отрисовкой это не есть хорошо, тем более, что оный встроен в Qt. Название: Re: оптимизация paint() QGraphicsItem'а Отправлено: AlexeyChe от Март 18, 2011, 14:16 Пока не покажешь как отрисовываешь элементы... окей Код: void PolarAxis::paint(QPainter *p, const QStyleOptionGraphicsItem *option,QWidget *widget) масштабирование: Код: void PolarPlot::resizeEvent(QResizeEvent *re) Название: Re: оптимизация paint() QGraphicsItem'а Отправлено: GreatSnake от Март 18, 2011, 14:23 Где PolarAxis::boundingRect() ?
Зачем аллакируете в куче и забываете Цитировать QPen *dotPen=new QPen(Qt::DashDotLine); ???QRect *rct=new QRect(0,0,re->size().height()-25,re->size().width()-25); Зачем при ресайзе меняете размер сцены и потом применяете матрицу? Чем QGraphicsView::fitInView() не устроил? Чем не устроил QString::number() при отрисовке числа? Название: Re: оптимизация paint() QGraphicsItem'а Отправлено: AlexeyChe от Март 18, 2011, 14:56 Где PolarAxis::boundingRect() ? Код: QRectF PolarAxis::boundingRect() const без boundingRect ничего бы и не запустилось, так что я перенес этот пункт в категорию "очевидное" вообще по сути, если убрать всё масштабирование, припонки с double buffering, и прочую ересь, проект будет и так страшно лагать, рисуя только оси ЗЫ. про FitInView, просто незнал, спасибо Название: Re: оптимизация paint() QGraphicsItem'а Отправлено: GreatSnake от Март 18, 2011, 15:06 Дело в том, QGraphicsItem заточен под динамику, а PolarAxis по сути статика.
Поэтому предлагаю перенести отрисовку PolarAxis в свою PolarPlot::drawBackground(). Если оставить PolarAxis элементом, то т.к. он является фоном для других мелких элементов, то он будет всегда перерисовываться при изменении последних. А это явные и большие тормоза. Уже не раз здесь поднималась такая проблема. Странно, что в Qt книжках про такие ньюансы ни слова. Может когда-нибудь соберусь написать "tips & tricks" про QGraphicsView. Название: Re: оптимизация paint() QGraphicsItem'а Отправлено: AlexeyChe от Март 18, 2011, 15:16 GreatSnake, спасибо большое!
и впрямь странно что в книжках нету только вот на будущее, у меня ведь элементов будет не меньше чем line'ов и string'овых лейблов на осях, что мне почитать чтобы делать нормальное отображение? да и Pixmap, как правильно его использовать. я руководствовался в основном этой статьей http://doc.trolltech.com/qq/qq06-flicker-free.html#paintingbycandlelight сделал через drawBackgroung, нормально, только вот при изменении размеров, или наезде другого окна, то есть при любом намеке на repaint лагает. а значит фиговый встроенный double buffering или я не умею им пользоваться Название: Re: оптимизация paint() QGraphicsItem'а Отправлено: GreatSnake от Март 18, 2011, 21:45 Цитировать или я не умею им пользоваться Более чем уверен, что именно так)Цитировать при любом намеке на repaint лагает Как это проявляется? Давай код drawBackground().Название: Re: оптимизация paint() QGraphicsItem'а Отправлено: m_ax от Март 18, 2011, 22:05 Хм..
Цитировать Код
Во-вторых из-за него у вас утечка, поскольку не видно где он уничтожается В-третьих Цитировать Код
А теперь представте, что будет при интенсивном ресайзе и отрисовки.. Название: Re: оптимизация paint() QGraphicsItem'а Отправлено: AlexeyChe от Март 19, 2011, 13:11 я разобрался с QPixmap и QImage, и отрисовка теперь происходит только тогда когда нужно
и как следствие отсутствуют тормоза масштабирование через FitInView, и вообще картина стала гораздо лучше, сейчас буду засовывать сцену в отдельный поток, и тогда вообще будет счастье всем спасибо, если ещё есть какие нибудь рекомендации, буду благодарен Цитировать Во-вторых из-за него у вас утечка, поскольку не видно где он уничтожается я честно сказать пока не разобрался в memory management qt, я почитаю насчёт этого момента, спасибоНазвание: Re: оптимизация paint() QGraphicsItem'а Отправлено: psgenn от Март 27, 2011, 13:58 А как собственно засунуть сцену в отдельный поток?
|