Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: solo700 от Январь 23, 2010, 20:14



Название: QPainter на QGraphicsView
Отправлено: solo700 от Январь 23, 2010, 20:14
Вопрос в следующем ...  QGraphicsView -> QGraphicsScene ... вывод идет на сцену. Всё нормально работает. Надо рисовать прямоугольную область выделения - ну для зуминга - "увеличить-уменьшить" либо просто зону, для выделения объектов. Пишу обработчик для
void KViewMap::mousePressEvent(QMouseEvent *mouseEvent);
void KViewMap::mouseMoveEvent(QMouseEvent *mouseEvent);
void KViewMap::mouseReleaseEvent(QMouseEvent *mouseEvent);
динамический прямоугольник рисую на сцене - на перемещении мышки изменяются параметры прямоугольника типа
polygonItem->setPolygon(polyNew);   -  всё просто, всё работает. Работает замечательно если 5, 10, 300 объектов на сцене. Если 30000 объектов, область выделения отрисовывается уже с затыками - тормозит, не успевает за мышкой. У меня будет порядка 150000 объектов. Как ускорить ?
Решил рисовать не на сцене а непосредственно на view. На тех же самых обработчиках мышки.
Ну там упростим старый, новый прямоугольник - затирание старого - рисование нового.
Код на перемещении мыши :

Код:
QPainter *paint=new QPainter(this); // здесь объявление было в классе - инициализация по нажатию мыши
paint->setPen(QPen(Qt::black, 2));
paint->drawRect(LastRect);
Код:
или
Код:
QPainter paint;
paint.begin(this);
paint.setPen(QPen(Qt::black, 2));
paint.drawRect(LastRect);
paint.end();
Код:
или
Код:
QPainter paint;
paint.begin(viewport());
paint.setPen(QPen(Qt::black, 2));
paint.drawRect(LastRect);
paint.end();
Код:

Всё это выдает сообщение  "Painter not active". Подскажите пожалуйста что не так ?
Очень интересует как ускорить отрисовку на сцене и почему не рисует на виде ?


Название: Re: QPainter на QGraphicsView
Отправлено: lit-uriy от Январь 23, 2010, 20:28
штатный прямоугольник выделения тормозит при таком кол-ве объектов? Если нет, то яб лучше его использовал, вместо самостоятельного рисования.


Название: Re: QPainter на QGraphicsView
Отправлено: solo700 от Январь 23, 2010, 21:39
В Qt я новичок ... похоже что то упустил ... чтотакое  "штатный прямоугольник выделения" ?


Название: Re: QPainter на QGraphicsView
Отправлено: Igors от Январь 23, 2010, 21:44
Если Вам даже удастся его уговорить (не знаю как) - то все равно рисование НЕ из метода paintEvent - это хороший способ нажить себе кучу проблем. Я бы делал "легально", примерно так

- нужно отрисовать по мышe - вызываю repaint, но перед этим ставлю флаг напр. modeDrawMouse

- в перекрытом paintEvent смотрю - если есть modeDrawMouse, то мне не надо рисовать примитивы, не надо чистить background и.т.п. - надо только рисовать необходимое (часто xor)


Название: Re: QPainter на QGraphicsView
Отправлено: lit-uriy от Январь 23, 2010, 22:36
Цитировать
чтотакое  "штатный прямоугольник выделения"
смотри QGraphicsView::setDragMode(QGraphicsView::RubberBandDrag);

Вообще у тебя несколько проблем в приведённом описании и коде.
1) как упомянуто Игорем, в Qt рисовать на виджетах можно только в их методе paintEvent (экстра случаи типа overpainting я не рассматриваю)
2) в коде ты всякий раз при нажатии конпки мыша создаёшь рисовальщик (QPainter), но никогда его не удаляешь - память утекает.
3) Пока существует рисовальщик связанный с этим виджетом, другой рисовальщик работать не может, отсюда сообщение "Painter not active"
4) с терминологией всё как-то плохо:
Цитировать
QGraphicsView -> QGraphicsScene ... вывод идет на сцену
что значит "вывод идёт на сцену"?

Цитировать
динамический прямоугольник рисую на сцене
тоже не понятно, на сцене рисовать нельзя. Т.к. Сцена - контейнер, примерно как QList, только интелектуальный. Видимо речь идёт о создании элемента (наследника QGraphicsItem)


Название: Re: QPainter на QGraphicsView
Отправлено: solo700 от Январь 25, 2010, 01:32
Спасибо за ответы !
QGraphicsView::setDragMode(QGraphicsView::RubberBandDrag); не помог - работает ещё медленнее, чем мой первый вариант.
Вообщем то я подозревал, что QPainter надо использовать в методе paintEvent. Попробую реализовать предложение Игоря.
Насчет утечки памяти :
QPainter *paint=new QPainter(this)   -  здесь я сам бы позаботился об очистке.
QPainter paint;  -  у этого объекта область видимости - блок, так что разрушится по выходу.
Насчет терминологии ... согласен ... исправлюсь.  :)