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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: [практически решено] определение видимой части QGraphicsScene в QGraphicsView  (Прочитано 16258 раз)
_Vitaliy_
Гость
« : Март 19, 2012, 21:24 »

Доброго времени суток.
Есть вопрос такого характера.

Есть модуль, в конструкторе которого создаю:  
    
Код:
...
    ui->setupUi(this);
    scene = new QGraphicsScene(this);
    ui->graphicsView->setScene(scene);
    ...
далее по коду устанавливаю размер сцены:  
Код:
scene->setSceneRect(0, 0, Size + 50, razmer_sceni_po_y - 30); 
где Size может принимать довольно большое значение.

рисую график
Код:
QGraphicsItem *item = new Grafik(...);  

Возникают "тормоза" при передвижении графика вверх-вниз (нужно по задаче).
Скорее всего происходит из-за того что сцена может быть в несколько десятков раз больше чем визуальный ui->graphicsView и передвигается весь график (включая части которые не видно).

Вопрос: как определить видимую часть QGraphicsScene в ui->graphicsView?
« Последнее редактирование: Март 21, 2012, 18:59 от _Vitaliy_ » Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #1 : Март 20, 2012, 10:31 »

Код
C++ (Qt)
ui->graphicsView->mapToScene( QRect( 0, 0,  ui->graphicsView->viewport()->width(),  ui->graphicsView->viewport()->height() ) )
Записан

Qt 5.11/4.8.7 (X11/Win)
_Vitaliy_
Гость
« Ответ #2 : Март 21, 2012, 18:59 »

GreatSnake спасибо Вам, практически получилось то, что я хотел.

Остается вопрос такого характера.
Если сцена не помещается во вьювере, то появляется горизонтальный скроллер, например я перемещаю скроллер на некоторую позицию, как узнать в этом случае какой участок сцены видно во вьювере?
Записан
popper
Гость
« Ответ #3 : Март 22, 2012, 23:26 »

Вопрос: как определить видимую часть QGraphicsScene в ui->graphicsView?

как узнать в этом случае какой участок сцены видно во вьювере?

никак не могу понять разницу между этими двумя вопросами
Записан
Bepec
Гость
« Ответ #4 : Март 23, 2012, 08:01 »

И не пытайся... Это философия Йоды.
"Это есть дерево. Это дерево есть?"
Записан
_Vitaliy_
Гость
« Ответ #5 : Март 23, 2012, 08:30 »

Идея в следующем (рассматривается только по ширине):
Вариант 1. При выводе Сцена вмещается в Виев, тогда ничего пересчитывать не надо, просто отрисовать.

Вариант 2. При выводе Сцена гораздо больше Виев, первоначально нулевые координаты Виев и Сцены совпадают но сцена "простирается" вправо и большая часть ее не видна. Вариант, предложенный GreatSnake работает. Можно просчитать какой участок Сцены видим, отрисовать его, а потом все остальное.

Вариант 3. Пользователь передвинул скролл, например на середину Сцены, получается что Виев отображает середину Сцены, справа и слева находятся невидимые участки сцены. Вот здесь и основной вопрос: как узнать участок сцены, который отображает Виев в этом случае???

Напрашивается работать через Скролл, зная размер Виев, размер Сцены и значение скролла (пока не знаю как) можно высчитать видимый участок Сцены.
Может нужно через слот изменения значения скролла...

П.С. Извиняюсь, если "многа букф" но проблему изложил по моему ясно.
П.П.С. Если кто предложит более рациональный вариант, буду премного благодарен.
  
« Последнее редактирование: Март 23, 2012, 08:34 от _Vitaliy_ » Записан
Barmaglodd
Гость
« Ответ #6 : Март 23, 2012, 09:48 »

Отрисовывай только видимую часть атема, и никаких пересчётов не надо.
В QGraphicsItem::paint передаётся прямоугольник, который видим QStyleOptionGraphicsItem::exposedRect.
Но если ты набил сцену миллионом айтемов, то ССЗБ Подмигивающий
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #7 : Март 23, 2012, 10:02 »

П.П.С. Если кто предложит более рациональный вариант, буду премного благодарен.
Абсолютно не понятно в чём проблема и что нужно на выходе и чем не устраивает стандартное поведение GV Непонимающий
Записан

Qt 5.11/4.8.7 (X11/Win)
V1KT0P
Гость
« Ответ #8 : Март 23, 2012, 11:58 »

П.С. Извиняюсь, если "многа букф" но проблему изложил по моему ясно.
П.П.С. Если кто предложит более рациональный вариант, буду премного благодарен.
Да не совсем ясно. Если ты добавляешь итемы на графсцену то графсцена сама смотрит какие итемы видны те и перерисовывает.
Записан
_Vitaliy_
Гость
« Ответ #9 : Март 23, 2012, 13:14 »

вечером выложу исходники и добавлю немного картинок, дабы не вводить в заблуждение комьюнити.
Записан
_Vitaliy_
Гость
« Ответ #10 : Март 23, 2012, 19:33 »

Вот проект.
Сильно не пинайте, только учусь.

В vizual_grifik происходит вызов рисования
Код:
QGraphicsItem *item = new Grafik(model, Qt::red, 3, min, max);
item->setPos(QPointF(0, 200));
grafik отвечает за рисование, остальное можно опустить.

В папке dannie лежат тестовые файлы. Если открыть big-файл то заметны тормоза, особенно при попытке перемещения графиков по оси Y.

П.С. кстати где-то при построении графиков, течет память...
Записан
_Vitaliy_
Гость
« Ответ #11 : Март 24, 2012, 09:38 »

Цитировать
Отрисовывай только видимую часть атема, и никаких пересчётов не надо.
В QGraphicsItem::paint передаётся прямоугольник, который видим QStyleOptionGraphicsItem::exposedRect.

А как его туда передать?
В конструкторе я рисую путь
Код:
Grafik::Grafik(QStandardItemModel *model, const QColor &color, int stolbec, int min, int max)

В моем случае boundingRect ограничивается прямоугольником ограничивающим график
Код:
QRectF Grafik::boundingRect() const
{
    return QRectF(0, 0, size_x + 5, size_y);
}
Далее
Код:
QPainterPath Grafik::shape() const
{
    QPainterPath pathik;
    pathik.addPath(path);
    return pathik;
}
И собственно рисование
Код:
void Grafik::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(widget);

    painter->setPen(QPen(color));
    painter->drawPath(path);
}
Нашел в доках что нужно флаг передать:
Код:
This member is only initialized for items that have the QGraphicsItem::ItemUsesExtendedStyleOption flag set.
Записан
_Vitaliy_
Гость
« Ответ #12 : Март 25, 2012, 12:16 »

Правильно ли будет использовать следующий алгоритм:
1. В ГрафикВиеве на событии МаусРелиз (пользователь передвинул скролл на некоторую позицию) определяем видимую часть Сцены используя
Код:
graphicsView->mapToScene( QRect( 0, 0,  ui->graphicsView->viewport()->width(),  ui->graphicsView->viewport()->height() ) )
2. Сначала перерисовываем видимую часть сцены а потом невидимые участки сцены.

Пробовал для тема такие флаги
Код:
item->setCacheMode(QGraphicsItem::ItemCoordinateCache); и item->setCacheMode(QGraphicsItem::DeviceCoordinateCache);

В конструкторе тоже пробовал оптимизацию
Код:
ui->graphicsView->setOptimizationFlags(QGraphicsView::DontSavePainterState);
ui->graphicsView->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
ui->graphicsView->setCacheMode(QGraphicsView::CacheBackground);
но что-то не заметно прироста, "большой" график все равно "дергается" если его перемещать вверх-вниз...
Записан
Bepec
Гость
« Ответ #13 : Март 25, 2012, 13:31 »

Зачем невидимые перерисовывать Оо? Они ж невидимые ёмое.
Записан
_Vitaliy_
Гость
« Ответ #14 : Март 25, 2012, 18:41 »

Может я не до конца понимаю концепцию рисования...
В одной из форм (пусть будет vizual_grifik) я вызываю:
Код:
QGraphicsItem *itema = new Grafik(model, Qt::green, 4, min, max);
далее в конструкторе (пусть Grafik) рисую path
в этом же модуле Grafik вызывается отрисовка
Код:
void Grafik::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(widget);

    painter->setPen(QPen(color));
    painter->drawPath(path);
}
Если рисовать в непосредственно в paint, то заметны тормоза.
При этом в самой организации кода мне вроде все понятно.

Теперь рассмотрим вариант:
ГрафикСцен"а не умещается в ГрафикВиев, есть скролл по оси ОХ, пользователь передвигает мышкой скролл не некоторую позицию.
В этом случае происходит перерисовка Grafik::paint(...)?
если да, то может есть смысл организовать перерисовку в конструкторе в цикле с видимыми координатами ГрафикСцен в ГрафикВиев или я заблуждаюсь.
Цитировать
Зачем невидимые перерисовывать Оо? Они ж невидимые ёмое.
А если пользователь после перемещения графика по OY передвинет скролл на некоторую иную позицию по OX, то "перемещенный" график будет ли отображаться корректно, т.е. будут ли "артефакты" на графике после того как пользователь сначала перемещал график вверх-вниз, а потом передвинул скроллом сцену во вьюшке?  
Прошу пояснить.
 
« Последнее редактирование: Март 26, 2012, 07:09 от _Vitaliy_ » Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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