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

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

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: работа с QGraphicsScene  (Прочитано 20285 раз)
deefox
Гость
« : Сентябрь 19, 2016, 13:04 »

Доброго времени суток!

Поделитесь опытом.
По сети приходят данные о пикселях, я их отрисовываю в QImage и посылаю сигналом Qimage в главный поток, где добавляю на сцену в виде QGraphicsPixmapItem.

Суть в том, что объектов много, и подлагивает гуи.

Но хотелось бы еще и удалять итемы например если их будет 65к. пытался посредством
Код:
    if(itemsPixmap.isEmpty()){
        itemsPixmap.enqueue(scene->addPixmap(QPixmap::fromImage(itemPixmap)));
        itemsPixmap.last()->setPos(0,0);
    }
    else
    {
        QPointF tempPoint = itemsPixmap.last()->pos();
        tempPoint.setX(tempPoint.x() + 1.0);
        itemsPixmap.enqueue(scene->addPixmap(QPixmap::fromImage(itemPixmap)));
        itemsPixmap.last()->setPos(tempPoint);
    }
    if(itemsPixmap.count() >= 30000){
        scene->removeItem(itemsPixmap.at(0));
        itemsPixmap.dequeue();
    }

но лаги неимоверные, да и отрисовка ужасная становится. Есть ли возможность работать со сценой в отдельном потоке? или как мне это оптимизировать эту работу?

« Последнее редактирование: Сентябрь 19, 2016, 13:06 от deefox » Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #1 : Сентябрь 19, 2016, 15:04 »

Создать на сцене один QGraphicsPixmapItem и обновлять только его содержимое, например?
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
deefox
Гость
« Ответ #2 : Сентябрь 19, 2016, 15:15 »

Создать на сцене один QGraphicsPixmapItem и обновлять только его содержимое, например?

размер элементов 1x4к   1x16к  1x32к, цельный итем программа не тянет.

По сети приходят пакеты размером 1318, самое оптимальное, это рисовать полные линии. + udp, часть может потеряться
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #3 : Сентябрь 19, 2016, 16:40 »

32k точек? это картинка всего 320 на 100 пикселей...

Вообще, не совсем понятна вся картина.
Что приходит? Как часто? Как это должно выглядеть для пользователя?
Скриншот бы не помешал...
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
deefox
Гость
« Ответ #4 : Сентябрь 20, 2016, 12:32 »

32k точек? это картинка всего 320 на 100 пикселей...

Вообще, не совсем понятна вся картина.
Что приходит? Как часто? Как это должно выглядеть для пользователя?
Скриншот бы не помешал...
`

по udp приходит пиксели,  сама картинка градиента серого т.е. 1 пакет 1318
Код:
qRgb(data[i],data[i],data[i])
в отдельном потоке отрисовываю их в линию, в зависимости от режима отрисовки(линия может быть 1x4к   1x16к  1x32к  (w х h))

"Пытался для экономии сделать через undexed8, но работать стала хуже, поэтому использую формат QImage RGB32"

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

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

Тут и началась вся проблема. при удалении
Код:
    scene->removeItem(itemsPixmap.dequeue());
    mute.unlock();
//или
    scene->removeItem(itemsPixmap.at[0]);
itemsPixmap.dequeue()
    mute.unlock();
сцена становится мертвой
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #5 : Сентябрь 20, 2016, 12:44 »

а зачем это вообще через сцену делать?
по линиям в принципе никто не делат, это не будет нормально работать никогда.
не проще завести один виджет и на нём рисовать пиксели через QImage?
или зум нужен? если так, то делаем только один QGraphicsPixmapItem и за раз обновляем только одну строку в нём.
« Последнее редактирование: Сентябрь 20, 2016, 12:46 от Racheengel » Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
deefox
Гость
« Ответ #6 : Сентябрь 20, 2016, 13:10 »

а зачем это вообще через сцену делать?
по линиям в принципе никто не делат, это не будет нормально работать никогда.
не проще завести один виджет и на нём рисовать пиксели через QImage?
или зум нужен? если так, то делаем только один QGraphicsPixmapItem и за раз обновляем только одну строку в нём.

да, нужен зум, без изменения изначальной картинки, плюс возможность изменить ракурс(по точно не известно нужно ли).

почему именно линии = мне приходит по сути линия, изначально я из сразу же и отрисовывал, для лучшей работы я начал рисовать  сразу конечные линии а не части как изначально, то есть - пришло 5 пакетов, из них собрал одну линиию и отрисовал - подсчитал потери и переключиллся на другую линию

была идея с тайтлами, но по производительность отрисовки меньше на слабеньком компе почти в 2.5 раза - тайтлы правдо были 4к на 4к

а вот на счет одного итема не пробывал: допустим у нас итем - на нем изначально как то размер задать нужно? приблизительно на экран при самом сильном уменьшении помещается 45к x 32к. Но не будет ли такой же эффект? передаем картинку в главное окно и там добавляем в итем?
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #7 : Сентябрь 20, 2016, 14:42 »

должна быть одна картинка фиксированного размера (пустая изначально).
по мере прихода данных, картинка обновляется и пакуется на сцену.
картинку хранить в QImage, там есть метод scanLine, который дает поинтер на строку в памяти (туда пишем).
чтоб было еще быстрее, можно кастомный итем сделать, переопределить в нем paint и напрямую отрисовывать данные.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
deefox
Гость
« Ответ #8 : Сентябрь 20, 2016, 16:55 »

должна быть одна картинка фиксированного размера (пустая изначально).
по мере прихода данных, картинка обновляется и пакуется на сцену.
картинку хранить в QImage, там есть метод scanLine, который дает поинтер на строку в памяти (туда пишем).
чтоб было еще быстрее, можно кастомный итем сделать, переопределить в нем paint и напрямую отрисовывать данные.

ну вот линии и были QImage фиксированного размера(линии)

Код:
        curQImageMode1.fill(Qt::white);
        imagePixelMode1 = reinterpret_cast<uint *>(curQImageMode1.bits());

            for (int i = 0; i < 1318; ++i) {
                //                curQImage.setPixel(0,i,qRgb(data[i],data[i],data[i]));
                imagePixelMode1[i] = qRgb(data[i],data[i],data[i]);

            }

а вот по поводу рисования сразу в итем, передавать в главный поток уже конечный итем, и его добавлять на сцену надо попробовать.


но вот по поводу удаления верен ли такой подход?

Код:
    if(itemsPixmap.count() >= 30000){
        scene->removeItem(itemsPixmap.at(0));
        itemsPixmap.dequeue();
    }


Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #9 : Сентябрь 20, 2016, 16:59 »

Я имею в виду, надо сделать один QImage и в нем рисовать 30000 или сколько там линий.

Удаление тоже не будет работать, надо как то так:

  while(itemsPixmap.count() >= 30000){
        scene->removeItem(itemsPixmap.first());
        delete itemsPixmap.takeFirst();
    }
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
deefox
Гость
« Ответ #10 : Сентябрь 22, 2016, 09:43 »

Я имею в виду, надо сделать один QImage и в нем рисовать 30000 или сколько там линий.

Удаление тоже не будет работать, надо как то так:

  while(itemsPixmap.count() >= 30000){
        scene->removeItem(itemsPixmap.first());
        delete itemsPixmap.takeFirst();
    }

В целой картинкой я пытался, мой компьютер фактически не смог работать с  целой картинкой в 60к(может и больше) х 32к. рисование и так нормально вроде все вырисовывает, чуть подправил отрисовку в QImage и в принципе летает, но вот с удаление,  гуи виснет. Может можно ли поместить процесс удаления в отдельный поток?
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #11 : Сентябрь 22, 2016, 11:15 »

хм... а зачем вообще что-либо тогда удалять?
пусть линии сидят себе на сцене.
пришла новая инфа - сдвинуть все линии (по координатам) вниз на 1,
последнюю переместить в позицию 0 и записать в нее пиксели.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
deefox
Гость
« Ответ #12 : Сентябрь 22, 2016, 15:12 »

хм... а зачем вообще что-либо тогда удалять?
пусть линии сидят себе на сцене.
пришла новая инфа - сдвинуть все линии (по координатам) вниз на 1,
последнюю переместить в позицию 0 и записать в нее пиксели.

Условно я говорю, что у нас картинка там больших размеров -  я назвал цифру, при том чтобы самая большая линии уместилась без скрола, а там дальше если нужно приблизить, в ширину поместится пикселей допустим 60 к... полностью такой объем сцены заполнится чуть больше минуты(смотря какая скорость ethernet) -  а если прием будет длится пол часа, мне нужно как то освободить место для будущей информации, я думал способом освободить место и сразу его заполнить.

просто по вашему способу я не умещу столько информации, да и не нужна она мне будет.

Я тестировал сколько смогу принять  без сдвигов, удаления и прочего - вышло в ширину около 65 к пикселей и программа крашилась (и то там 80 % занимали маленькие элементы из этого трио), причем оперативки было еще много свободной. так что по видимому сцена имеет свой придел тоже.
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #13 : Сентябрь 22, 2016, 15:41 »

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

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
deefox
Гость
« Ответ #14 : Сентябрь 22, 2016, 15:57 »

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

что вы имеете ввиду под собственной отрисовкой? у QGraphicsView вроде есть такая функция. что он отображает только видимую часть сцены. у меня идет уменьшение матрицы в 0,22хххх в принципе, все что за ее пределами я и хочу как то динамически удалять со сцены, сдигая все влево на 1 освобождая место для сл элемента, при этот самом размере (но нужно будет и увеличивать zoom).
Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


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