Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Pritcher от Декабрь 25, 2014, 08:33



Название: [Решено]Фон в QGraphicsView
Отправлено: Pritcher от Декабрь 25, 2014, 08:33
Привет!
По сабжу: делаю графический редактор в целях обучения. Хочу сделать возможным изменение стандартного фона на картинку.
Почитал источники, написано, что нужно наследовать класс QGraphicsView и переопределить в нем метод drawBackground. Код прилагается. У редактора на тулбаре есть кнопка, соединенная коннектом со слотом загрузки картинки. Проблема в том, что если нажать на кнопку, фон перерисовывается не сразу, для перерисовки требуется нарисовать на сцене какую-либо фигуру и лишь тогда фон изменится. Почему так получается?
Помимо этого, когда фон изменился на нужную мне картинку, он не занимает всю область отображения, картинка не ресайзится, но вызов scaled с параметрами прямоугольника сцены я делаю.

Код:
#include "MyGraphicsView.h"

MyGraphicsView::MyGraphicsView( QWidget * parent ) :
QGraphicsView( parent )
{
setSceneRect( 0, 0, 500, 500 );
backgroundImage = 0;
setViewportUpdateMode( QGraphicsView::FullViewportUpdate );
}

void MyGraphicsView::drawBackground( QPainter * painter, const QRectF & rect )
{
if ( backgroundImage == 0 ) {
QGraphicsView::drawBackground( painter, rect );
}
else {
painter->save();
painter->drawImage( 0, 0, *backgroundImage );
painter->restore();
}
}

void MyGraphicsView::slotSetBackground()
{
//TODO_1: add QFIleDialog
backgroundImage = new QImage;
backgroundImage->load( "Resources/background.png" );
backgroundImage->scaled( sceneRect().width(), sceneRect().height() );
}


Название: Re: Фон в QGraphicsView
Отправлено: Fregloin от Декабрь 25, 2014, 11:11
Во первых после того как вы загрузили картинку что бы обновился задний фон, нужно вызвать метод invalidate, в котором указать, какой слой обновился (Foreground,Background). Почитайте в доках. Я с этим лично возился когда нужно было программную сетку рисовать.
Во вторых при перерисовке заднего фона передается QRectF в котором указывается текущая область перерисовки, поэтому рационально отрисовывать только часть картинки а не всю сразу. Так как при небольшом перемещении элемента у вас задний фон будет перерисовываться много раз целиком - накладные расходы. Тем более в drawImage есть параметр прямоугольных областей отображения картинки.


Название: Re: Фон в QGraphicsView
Отправлено: GreatSnake от Декабрь 25, 2014, 11:43
Проблема в том, что если нажать на кнопку, фон перерисовывается не сразу, для перерисовки требуется нарисовать на сцене какую-либо фигуру и лишь тогда фон изменится.
Делай так
Код
C++ (Qt)
QGraphicsView::viewport()->update();

Помимо этого, когда фон изменился на нужную мне картинку, он не занимает всю область отображения, картинка не ресайзится, но вызов scaled с параметрами прямоугольника сцены я делаю.
Делай как здесь (http://www.prog.org.ru/index.php?topic=8266.msg102364#msg102364).


Название: Re: Фон в QGraphicsView
Отправлено: Pritcher от Декабрь 25, 2014, 18:51
Invalidate я не нашёл как правильно использовать.
Если в следующем методе вместо (0,0) подставить scenerect(), то фон все же грузится и ресайзится, как надо.
Код:
painter->drawImage( rect, *backgroundImage )

А вот проблему с мгновенным рисованием фона (без рисования посторонней фигуры) так и не удалось решить


Название: Re: Фон в QGraphicsView
Отправлено: GreatSnake от Декабрь 25, 2014, 19:20
А вот проблему с мгновенным рисованием фона (без рисования посторонней фигуры) так и не удалось решить
Т.е. предыдущий пост мы в упор не видим ???


Название: Re: Фон в QGraphicsView
Отправлено: Pritcher от Декабрь 26, 2014, 17:50
Цитировать
Т.е. предыдущий пост мы в упор не видим  ???

Предложенный вами метод не сработал, поэтому я и написал, что не удалось решить проблему


Название: Re: Фон в QGraphicsView
Отправлено: GreatSnake от Декабрь 26, 2014, 17:52
Предложенный вами метод не сработал, поэтому я и написал, что не удалось решить проблему
Т.е. QGraphicsView::viewport()->update() не работает?
Не верю!


Название: Re: Фон в QGraphicsView
Отправлено: Pritcher от Декабрь 26, 2014, 17:55
 GreatSnake, Оба ваших способа испробовал, оба не помогли. На другой оси то же самое поведение. Право, сам удивлен.

Код:
void MyGraphicsView::drawBackground( QPainter * painter, const QRectF & rect )
{
if ( backgroundImage == 0 ) {
QGraphicsView::drawBackground( painter, rect );
}
else {
painter->save();
painter->drawImage( rect, *backgroundImage );
painter->restore();
QGraphicsView::viewport()->update();
}
}


Название: Re: Фон в QGraphicsView
Отправлено: Pritcher от Декабрь 26, 2014, 18:27
П.С.
Решил проблему с запаздывающей отрисовкой фона принудительным апдейтом сцены.
Спасибо за советы, тему можно закрывать.