Как получить видимый прямоугольник сцены QGraphicsView? - PullRequest
1 голос
/ 13 ноября 2011

Я отображаю карту, построенную в виде прямоугольника элементов QGraphicsPixmapitem (каждый элемент обозначает одну плитку карты). Поскольку моя карта довольно большая (около 30 МБ файлов PNG), я хочу иметь возможность загружать растровые изображения по требованию, только когда они видимы для пользователя в QGraphicsView, и выгружать, когда они становятся невидимыми.

Есть ли способ определить видимый прямоугольник сцены?

Ответы [ 2 ]

4 голосов
/ 04 июля 2014

Это дает вам видимый прямоугольник сцены:

sceneRect = graphicsView.mapToScene(graphicsView.rect()).boundingRect()

В случае присутствия преобразования сдвига или вращения это дает вам ограничивающий прямоугольник видимой области сцены. Если у вас нет таких преобразований (только сдвиг или увеличение), возвращаемый прямоугольник является точной областью сцены.

Теперь для вашей реальной задачи эффективно отобразить огромную карту тайлов в сцене? Вы можете загрузить плитки в фоновом режиме и сначала оценить, не оптимизирована ли ваша платформа Qt для больших растровых изображений, которые находятся за пределами видимого диапазона. 30 МБ также не кажутся такими большими, что не помещаются в память.

1 голос
/ 13 ноября 2011

QGraphicsView наследует функцию QWidget :: geometry ().Вы можете использовать это, чтобы определить его местоположение и размер в родительском виджете.(За пределами своего конструктора)

QGrapicsScene может быть больше, чем QGraphicsView.QGraphicsView по умолчанию добавит горизонтальные и вертикальные полосы прокрутки для размещения QGraphicsScene.Я предполагаю, что вы хотели бы сделать что-то вроде этого:

//create a QGraphicsScene (for this example *scene) that is the size of your entire map.
QGraphicsScene *scene=new QGraphicsScene(0,0,mapWidth,mapHeight);
//create a QGraphicsView* named view that is the size of your visible area
//I'm assuming visibleHeight and visibleWidth do not change (this is your viewing window)
QGraphicsView *view=new QGraphicsView(0,0,visibleWidth,visibleHeight);
view->setScene(scene);

Пусть пользователь контролирует положение x и y сцены, которое запускает некоторый пользовательский сигнал, например sceneMoved(int,int).Перед тем, как перерисовать сцену, позвоните в слот, чтобы проверить новое положение сцены:

connect(this,SIGNAL(sceneMoved(int,int)),this,SLOT(drawScene(int,int)));

void SomeClass::drawScene(int newX, int newY){
//if you already have a pointer to the scene do this, or call
//QGraphicsView::scene();
    int oldX=scene->geometry()->x();
    int oldY=scene->geometry()->y();
    //now that you have your oldX, oldY, newX, and newY, visibleWidth, visibleHeight
    //you can determine what you need to redraw, what you need to delete, and what can stay
}

Многое еще есть if..sese, но вы понимаете, в чем дело.Я предлагаю попробовать разбить вашу карту на квадраты размером с видимую область.

...