Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: Vladimir от Март 19, 2013, 10:15



Название: Тормоза при масштабировании QGraphicsView
Отправлено: Vladimir от Март 19, 2013, 10:15
Доброго дня! Такая ситуация:
Есть класс, связанный с виджетом Graphics View через меню "Преобразовать в ..."
Код:
class WindowDraw : public QGraphicsView
{
   ...
   private:
        QGraphicsScene    *scene;
   ...
}

Первый items, на всю область рисования, отображает картинку, в которую рисуется попиксельно некая полученная первичная информация.
Второй items отображает также картинку на всю область рисования (оба унаследованы от  public QGraphicsObject). Картинка второго items - это  QImage(width,height,QImage::Format_ARGB32_Premultiplied), в которой подсвечиваются пиксели (с размытием) имитируя некие появляющиеся метки (простые квадратики), их может быть много 10ки тыс! Поэтому этот способ позволяет быстро все отрисовывать, в отличие от создания каждой метки отдельным items. Метки появляются поверх первичной информации поэтому картинка прозрачная. Но оказалось в этом и проблема, когда начинается масштабирование, делается просто scale() Graphics View. Отрисовка первичной информации сразу затыкается и дело именно в прозрачности QImage, потомому что без этого слоя масштабируется все шустро..

есть ли способ это обойти при существующем методе рисования??!


Название: Re: Тормоза при масштабировании QGraphicsView
Отправлено: GreatSnake от Март 19, 2013, 10:30
Можно попробовать вообще отказаться от элементов и делать отрисовку первого в перегруженном QGraphicsScene/QGraphicsView::drawBackground(), а второго в QGraphicsScene/QGraphicsView::drawForeground().
Как делать отрисовку QImage см. здесь (http://www.prog.org.ru/index.php?topic=14327.msg93509#msg93509).


Название: Re: Тормоза при масштабировании QGraphicsView
Отправлено: Vladimir от Март 19, 2013, 11:35
Можно попробовать вообще отказаться от элементов и делать отрисовку первого в перегруженном QGraphicsScene/QGraphicsView::drawBackground(), а второго в QGraphicsScene/QGraphicsView::drawForeground().
Как делать отрисовку QImage см. здесь (http://www.prog.org.ru/index.php?topic=14327.msg93509#msg93509).

вроде рисует быстрее, не затыкается.. но еще пока недоразобрался! перенес только отрисовку первичной информации в
drawBackground()..

Можете пояснить в кратце, что конкретно делает этот код, который Вы привели по ссылке? Какой-то ручной пересчет масштаба..? а то у меня были реализованы масштабирование/панорамирование и пока не понятно куда оно и как двигается! =) картинка изначально у меня большего размера, чем область вывода, поэтому при рисовании я делал ей scale() и она просто центроровалась в сжатом виде.. а в данной функции масштабирование от чего будет зависить?

Код:
void YourScene::drawBackground( QPainter* p, const QRectF& clip )
{
if( !bg_image_ )   // QImage* bg_image_ - предварительно загруженная картинка
{
QGraphicsScene::drawBackground( p, clip );
return;
}
 
p->eraseRect( clip );
 
QMatrix wm( p->worldMatrix() );
 
if( wm.m11() != 1 &&
clip.intersects( bg_image_->rect() ) )
{
QImage img;
QRectF c( clip );
if( wm.m11() > 1 )
c.adjust( -1, -1, 1, 1 );
 
qreal cx = c.x();
qreal cy = c.y();
qreal cw = qMax( 16., c.width() );
qreal ch = qMax( 16., c.height() );
 
if( cx < 0 )
{
cw += cx;
cx = 0;
}
if( cy < 0 )
{
ch += cy;
cy = 0;
}
 
cw = qMin( cw, bg_image_->width() - cx );
ch = qMin( ch, bg_image_->height() - cy );
img = bg_image_->copy( QRectF( cx, cy, cw, ch ).toRect() );
cw = qRound( cw * wm.m11() );
ch = qRound( ch * wm.m11() );
img = img.scaled( (int) cw, (int) ch, Qt::IgnoreAspectRatio,
/*wm.m11() > .8 ? Qt::SmoothTransformation :*/ Qt::FastTransformation );
p->setWorldMatrix( QMatrix( 1, 0, 0, 1, wm.dx(), wm.dy() ) );
p->drawImage( QPointF( cx * wm.m11(), cy * wm.m11() ), img );
p->setWorldMatrix( wm );
} else
{
p->drawImage(
QPointF( clip.x(), clip.y() ),
*bg_image_,
QRectF( clip.x(), clip.y(),
qMin( clip.width(), qreal( bg_image_->width() ) ),
qMin( clip.height(), qreal( bg_image_->height() ) ) ) );
}
}


Название: Re: Тормоза при масштабировании QGraphicsView
Отправлено: GreatSnake от Март 19, 2013, 11:42
Данный код отрисовывает соответствующую часть QImage (bg_image_) во вьюпорте.
Если задано масштабирование, то картинка перед отображением тоже масштабируется.
bg_image_ - оригинальное изображение в 100% масштабе.
Никаких дополнительных действий не требуется.
Масштабирование задаётся через QGraphicsView::scale() либо через QGraphicsView::fitInView(), если требуется полностью отобразить картинку.