Russian Qt Forum
Ноябрь 25, 2024, 00:45 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: [Решено]Фон в QGraphicsView  (Прочитано 6480 раз)
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() );
}
« Последнее редактирование: Декабрь 26, 2014, 18:49 от Pritcher » Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #1 : Декабрь 25, 2014, 11:11 »

Во первых после того как вы загрузили картинку что бы обновился задний фон, нужно вызвать метод invalidate, в котором указать, какой слой обновился (Foreground,Background). Почитайте в доках. Я с этим лично возился когда нужно было программную сетку рисовать.
Во вторых при перерисовке заднего фона передается QRectF в котором указывается текущая область перерисовки, поэтому рационально отрисовывать только часть картинки а не всю сразу. Так как при небольшом перемещении элемента у вас задний фон будет перерисовываться много раз целиком - накладные расходы. Тем более в drawImage есть параметр прямоугольных областей отображения картинки.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #2 : Декабрь 25, 2014, 11:43 »

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

Помимо этого, когда фон изменился на нужную мне картинку, он не занимает всю область отображения, картинка не ресайзится, но вызов scaled с параметрами прямоугольника сцены я делаю.
Делай как здесь.
Записан

Qt 5.11/4.8.7 (X11/Win)
Pritcher
Гость
« Ответ #3 : Декабрь 25, 2014, 18:51 »

Invalidate я не нашёл как правильно использовать.
Если в следующем методе вместо (0,0) подставить scenerect(), то фон все же грузится и ресайзится, как надо.
Код:
painter->drawImage( rect, *backgroundImage )

А вот проблему с мгновенным рисованием фона (без рисования посторонней фигуры) так и не удалось решить
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #4 : Декабрь 25, 2014, 19:20 »

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

Qt 5.11/4.8.7 (X11/Win)
Pritcher
Гость
« Ответ #5 : Декабрь 26, 2014, 17:50 »

Цитировать
Т.е. предыдущий пост мы в упор не видим  Непонимающий

Предложенный вами метод не сработал, поэтому я и написал, что не удалось решить проблему
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #6 : Декабрь 26, 2014, 17:52 »

Предложенный вами метод не сработал, поэтому я и написал, что не удалось решить проблему
Т.е. QGraphicsView::viewport()->update() не работает?
Не верю!
Записан

Qt 5.11/4.8.7 (X11/Win)
Pritcher
Гость
« Ответ #7 : Декабрь 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();
}
}
« Последнее редактирование: Декабрь 26, 2014, 17:57 от Pritcher » Записан
Pritcher
Гость
« Ответ #8 : Декабрь 26, 2014, 18:27 »

П.С.
Решил проблему с запаздывающей отрисовкой фона принудительным апдейтом сцены.
Спасибо за советы, тему можно закрывать.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.071 секунд. Запросов: 23.