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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: (РЕШЕНО) Сохранение и восстановление позиции вьюпорта на сцене  (Прочитано 5079 раз)
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« : Февраль 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() );
Я прав? Кто такое же делал - может есть более элегантный путь, и я его не увидел?
« Последнее редактирование: Февраль 22, 2015, 20:51 от Гурман » Записан

2^7-1 == 127, задумайтесь...
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #1 : Февраль 19, 2015, 22:19 »

а хрена там... QGraphicsView::scrollContentsBy(...) зачем-то сделан virtual protected  В замешательстве

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

2^7-1 == 127, задумайтесь...
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #2 : Февраль 19, 2015, 22:48 »

И со скроллбарами сразу не получается - если их двигать руками, они сигналы генерят, но если подвигать сцену под курсором, они молчат. А соответствующих сигналов у всяких ScrollArea не видно. Что-то тут сильно перемудрили...
« Последнее редактирование: Февраль 19, 2015, 22:50 от Гурман » Записан

2^7-1 == 127, задумайтесь...
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #3 : Февраль 19, 2015, 23:35 »

Че-то нихрена не получается и с сохранением-восстановлением положения вьюпорта. Первый вариант не работает, это вообще к вьюпорту отношения не имеет. Сделал сохранение положения вьюпорта таким макаром (gv это ui->graphicsView):

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

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

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

Судя по содержимому файла настроек, положение сохраняется, но восстановления нет.
« Последнее редактирование: Февраль 22, 2015, 18:49 от Гурман » Записан

2^7-1 == 127, задумайтесь...
CriDos
Гость
« Ответ #4 : Февраль 20, 2015, 09:55 »

Сцена имеет фиксированный размере?
Почему не применяется метод void QGraphicsView::​centerOn(const QPointF & pos)?
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #5 : Февраль 20, 2015, 12:02 »

Сцена имеет фиксированный размере?
Почему не применяется метод void QGraphicsView::​centerOn(const QPointF & pos)?

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

2^7-1 == 127, задумайтесь...
CriDos
Гость
« Ответ #6 : Февраль 20, 2015, 12:40 »

У себя только что проверил, отлично работает centerOn.
Т.е. наши действия:
1) Инициализируем сцену и объекты на ней, что бы сцена создала "рабочую область", которая растягивается объектами (QGraphicsScene::​itemsBoundingRect()).
2) Привязываем к сцене вьювер и делаем centerOn в пределах рабочей области (дальше и не пустит, пока не растянем сцену). 
« Последнее редактирование: Февраль 20, 2015, 13:00 от CriDos » Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #7 : Февраль 20, 2015, 15:44 »

И в результате получится совсем не то, что требуется.
Записан

2^7-1 == 127, задумайтесь...
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #8 : Февраль 22, 2015, 18:46 »

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

2^7-1 == 127, задумайтесь...
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #9 : Февраль 22, 2015, 19:06 »

Но остался вопрос - есть ли универсальный способ отслеживать факт изменения положения вьюпорта на сцене? Если ловить сигналы от скроллбаров, то они их излучают только если пользователь меняет положение кноба скроллбара, даже при нажатии на кнопки не выдает. Проблема в том, что позиция на вьюпорте меняется целой кучей других способов - перетаскивание сцены мышью, зум и т.д.

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

2^7-1 == 127, задумайтесь...
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #10 : Февраль 22, 2015, 20:52 »

Всё, нашел... сигналы valueChanged() испускаются скроллами при любых изменениях положения вьюпорта на сцене.

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

2^7-1 == 127, задумайтесь...
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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