Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: Гурман от Февраль 19, 2015, 14:11



Название: (РЕШЕНО) Сохранение и восстановление позиции вьюпорта на сцене
Отправлено: Гурман от Февраль 19, 2015, 14:11
Надо сохранять в настройках положение вьюпорта QGraphicsView на QGraphicsScene и восстанавливать при запуске. Влоб соответствующих простых вызовов типа
Код:
QPointF QGraphicsView::saveViewport(); 
void QGraphicsView::restoreViewport(QPointF)
нет. Также нет сигнала от QGraphicsView об изменении положения его вьюпорта на сцене. Получается немного косая конструкция:

1) для отслеживания изменений положения вьюпорта делаем один приемник сигналов перемещения от обоих скроллбаров вьюпорта
2) в этом приемнике положение вьюпорта получаем в виде
Код:
QPointF pos = ui->graphicsView->mapToScene( 0, 0 ); 
3) при выходе из приложения сохраняем положение вьюпорта в виде этого QPointF
4) при запуске приложения восстанавливаем положение вьюпорта с помощью
Код:
ui->graphicsView->scrollContentsBy( (int)pos.x(), (int)pos.y() );
Я прав? Кто такое же делал - может есть более элегантный путь, и я его не увидел?


Название: Re: Сохранение и восстановление позиции вьюпорта на сцене
Отправлено: Гурман от Февраль 19, 2015, 22:19
а хрена там... QGraphicsView::scrollContentsBy(...) зачем-то сделан virtual protected  :-\

то есть, без наследования QGraphicsView так не получится, а наследовать нельзя, всё в дизайнере сделано и отлажено


Название: Re: Сохранение и восстановление позиции вьюпорта на сцене
Отправлено: Гурман от Февраль 19, 2015, 22:48
И со скроллбарами сразу не получается - если их двигать руками, они сигналы генерят, но если подвигать сцену под курсором, они молчат. А соответствующих сигналов у всяких ScrollArea не видно. Что-то тут сильно перемудрили...


Название: Re: Сохранение и восстановление позиции вьюпорта на сцене
Отправлено: Гурман от Февраль 19, 2015, 23:35
Че-то нихрена не получается и с сохранением-восстановлением положения вьюпорта. Первый вариант не работает, это вообще к вьюпорту отношения не имеет. Сделал сохранение положения вьюпорта таким макаром (gv это ui->graphicsView):

Код:
    QPolygonF viewportF = gv->mapToScene( gv->viewport()->geometry() );

восстановление

Код:
    gv->ensureVisible( viewportF.boundingRect() );

Судя по содержимому файла настроек, положение сохраняется, но восстановления нет.


Название: Re: Сохранение и восстановление позиции вьюпорта на сцене
Отправлено: CriDos от Февраль 20, 2015, 09:55
Сцена имеет фиксированный размере?
Почему не применяется метод void QGraphicsView::​centerOn(const QPointF & pos)?


Название: Re: Сохранение и восстановление позиции вьюпорта на сцене
Отправлено: Гурман от Февраль 20, 2015, 12:02
Сцена имеет фиксированный размере?
Почему не применяется метод void QGraphicsView::​centerOn(const QPointF & pos)?

Сцена бесконечного размера.


Название: Re: Сохранение и восстановление позиции вью&#
Отправлено: CriDos от Февраль 20, 2015, 12:40
У себя только что проверил, отлично работает centerOn.
Т.е. наши действия:
1) Инициализируем сцену и объекты на ней, что бы сцена создала "рабочую область", которая растягивается объектами (QGraphicsScene::​itemsBoundingRect()).
2) Привязываем к сцене вьювер и делаем centerOn в пределах рабочей области (дальше и не пустит, пока не растянем сцену). 


Название: Re: Сохранение и восстановление позиции вьюпорта на сцене
Отправлено: Гурман от Февраль 20, 2015, 15:44
И в результате получится совсем не то, что требуется.


Название: (РЕШЕНО) Re: Сохранение и восстановление позиции вьюпорта на сцене
Отправлено: Гурман от Февраль 22, 2015, 18:46
Добился таки сохранения и восстановления положения вьюпорта. Работает последний способ, который я выше описывал, сохранение через mapToScene() и восстановление через ensureVisible(). Раньше не получалось, потому что я для пробы пытался сохранять позицию в своих настройках, а после их восстановления происходила замена сцены. Сейчас сделал как надо, позиция вьюпорта сохраняется в файле, описывающем сцену. Файл внутри XML, это муторнее, чем в настройках, и вообще выглядит кривобоко. Но работает. Только в вызове ensureVisible() 2 последних параметра надо принудительно делать 0,0.


Название: Re: (почти РЕШЕНО) Сохранение и восстановление позиции вьюпорта на сцене
Отправлено: Гурман от Февраль 22, 2015, 19:06
Но остался вопрос - есть ли универсальный способ отслеживать факт изменения положения вьюпорта на сцене? Если ловить сигналы от скроллбаров, то они их излучают только если пользователь меняет положение кноба скроллбара, даже при нажатии на кнопки не выдает. Проблема в том, что позиция на вьюпорте меняется целой кучей других способов - перетаскивание сцены мышью, зум и т.д.

И еще не вполне объяснимый момент - если сначала отрисовать сцену и установить вьюпорт, а потом показать главное окно вызовом show(), то вьюпорт оказывается смещен на несколько десятков пикселов по горизонтали влево. Размер смещения всегда один и тот же. Если буквально поменять местами загрузку сцены и показ окна, сначала показать окно, потом загрузить и нарисовать сцену, то всё хорошо. Выяснить где связь никак не получается, у меня просто не за что уцепиться - для показа вызываю стандартный метод QMainWindow::show(), который со сценой вообще никак не связан. И при загрузке сцены никаких изменений окна нет, только один вызов ensureVisible() для графического вида.


Название: Re: (РЕШЕНО) Сохранение и восстановление позиции вьюпорта на сцене
Отправлено: Гурман от Февраль 22, 2015, 20:52
Всё, нашел... сигналы valueChanged() испускаются скроллами при любых изменениях положения вьюпорта на сцене.

Еще одно место, где Qt неадекватен. Хотя бы врапперы какие-то для этого случая сделали, чтобы было проще пользоваться.