Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Bolonat от Август 15, 2017, 14:14



Название: Масштабирование и прокрутка графиков по отдельности
Отправлено: Bolonat от Август 15, 2017, 14:14
Мне нужно отобразить несколько графиков в одном окне. Надо иметь возможность масштабировать и прокручивать графики по отдельности. Для отображения одного графика использую QGLWidget. А как теперь лучше отобразить графики вместе? На ум приходит положить несколько QGLWidget (в каждом нарисован свой график) с прозрачным фоном друг на друга. Или лучше использовать сцену с графическим представлением? Или что-то еще? Посоветуйте...


Название: Re: Масштабирование и прокрутка графиков по отдельности
Отправлено: Bolonat от Август 21, 2017, 19:45
В результате на сцену кладу массив виджетов QOpenGLWidget с прозрачным фоном и размер каждого устанавливаю равным размеру формы. Все хорошо, графики отображаются, но при растягивании формы масшабирование виджетов выполняется скачками  :(.


Название: Re: Масштабирование и прокрутка графиков по отдельности
Отправлено: Racheengel от Август 21, 2017, 21:30
Не пойму, как тут прозрачный фон помогает...
QLayout уже не модно ? :)


Название: Re: Масштабирование и прокрутка графиков по отдельности
Отправлено: Bolonat от Август 22, 2017, 11:52
Не пойму, как тут прозрачный фон помогает...
QLayout уже не модно ? :)
Проблема в том, что при использовании QLayout  мне не удалось установить прозрачность виджета QOpenGLWidget , он отображается с черным фоном, хоть ты тресни. А вот если виджеты поместить на сцену, то прозрачность есть.
Я работаю в Qt три недели, возможно чего-то еще не понимаю, поэтому заранее прошу меня извинить за все глупости. :)
Мои графики имеют несколько сотен тысяч значений, занимают всю область окна и пересекаются друг с другом во множестве мест. Перерисовать отдельную область не получится. Поэтому изначально хотелось реализовать систему слоев, чтобы работать с каждым графиком отдельно в своем слое(масштабировать, изменять промежутки отображения) и не перерисовывать остальные. Задача поставлена реализовать в OpenGL. Поэтому и использую виджеты QOpenGLWidget с прозрачным фоном.  Прозрачность устанавливаю с помощью
Код:
setWindowOpacity(0.9); 
в конструкторе и
  
Код:
  QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
    f->glClearColor(0, 0, 0, 0);
в initializeGL().
Еще одна проблема - масштабирование всего окна приводит к скачкообразному масштабированию всех слоев - виджетов. После многочисленных экспериментов прихожу к выводу, что проблема в  QOpenGLWidget. Если взять и положить простые виджеты QWidget друг на друга:
Код:
chart::chart(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::chart)
{
    ui->setupUi(this);

    //Создаем первый виджет
    QWidget* topWidget=new QWidget(this);

    //layout, который кладется на само диалоговое окно
    QVBoxLayout* curLayout=new QVBoxLayout;
    curLayout->addWidget(topWidget);
    setLayout(curLayout);

    //layout, который кладется на первый виджет
    curLayout=new QVBoxLayout;
    topWidget->setLayout(curLayout);


    for (int i = 0; i<10; i++)
    {
        //Создать очередной виджет
        QWidget* w=new QWidget(this);
        topWidget=w;
        curLayout->addWidget(w);

        //Назначить виджету фон
        QPalette pall;
        pall.setColor(w->backgroundRole(), Qt::blue);
        w->setPalette(pall);
        w->setAutoFillBackground(true);

        //Создать на виджете layout
        curLayout=new QVBoxLayout;
        w->setLayout(curLayout);
    }
}

chart::~chart()
{
    delete ui;
}
Масштабирование окна выполняется идеально. Но если в этом же коде заменить QWidget на QOpenGLWidget то при масштабировании уже можно заметить скачкообразность и фон остается черным. А если заменить на QGLWidget, то при масштабировании эффект вас потрясет... :)

 


Название: Re: Масштабирование и прокрутка графиков по отдельности
Отправлено: deMax от Август 22, 2017, 12:05
Мне нужно отобразить несколько графиков в одном окне. Надо иметь возможность масштабировать и прокручивать графики по отдельности. Для отображения одного графика использую QGLWidget. А как теперь лучше отобразить графики вместе? На ум приходит положить несколько QGLWidget (в каждом нарисован свой график) с прозрачным фоном друг на друга. Или лучше использовать сцену с графическим представлением? Или что-то еще? Посоветуйте...
Ничего не понял? Вам графики нужны рядом или друг над другом? И зачем виджеты поверх друг друга рисовать если можно в одном виджете отрисовать?


Название: Re: Масштабирование и прокрутка графиков по отдельности
Отправлено: Bolonat от Август 22, 2017, 12:10
Ничего не понял? Вам графики нужны рядом или друг над другом? И зачем виджеты поверх друг друга рисовать если можно в одном виджете отрисовать?
То есть, считаете, перерисовать 30 графиков с 200 тыс точек в каждом при изменении одного, это нормально?   


Название: Re: Масштабирование и прокрутка графиков по отдельности
Отправлено: Igors от Август 22, 2017, 12:32
То есть, считаете, перерисовать 30 графиков с 200 тыс точек в каждом при изменении одного, это нормально?  
Считаю что да, нормально, на то и OpenGL/GPU. А можно и без него, буферирование никто  не отменял. А вот затея "каждый график в своем окне" явно нездоровая (и ненужная). Все рисуется в одном окне, но есть список графиков где можно из выбрать, включить, выключить


Название: Re: Масштабирование и прокрутка графиков по отдельности
Отправлено: Bolonat от Август 22, 2017, 13:05
Считаю что да, нормально, на то и OpenGL/GPU. А можно и без него, буферирование никто  не отменял. А вот затея "каждый график в своем окне" явно нездоровая (и ненужная). Все рисуется в одном окне, но есть список графиков где можно из выбрать, включить, выключить
Отлично! Рисую все графики в одном виджете QOpenGlWidget. Проблема с масштабированием остается. Тяну вправо край формы на 5 см и почти спустя секунду восстанавливается изображение.
Код:
void chart::resizeEvent(QResizeEvent* pe)
{
    ui->myGraphicsView->resize(width(),height());
    w->resize(ui->myGraphicsView->width(), ui->myGraphicsView->height());
}
Здесь w - это QOpenGLWidget.
А что такое буферирование? Где почитать?


Название: Re: Масштабирование и прокрутка графиков по отдельности
Отправлено: Igors от Август 22, 2017, 13:38
Отлично! Рисую все графики в одном виджете QOpenGlWidget. Проблема с масштабированием остается.
Так для QOpenGlWidget нужно resizeGL (а не resizeEvent)
А что такое буферирование? Где почитать?
Рисуете каждый гоафик в своем буфере (QImage), а потом шлепаете все буфера в окно. А если с OpenGL то лучше использовать VBO (по сути тоже буфер)

Также графики могут иметь разный иасштаб по Y. Стандартные решения: опция "AutoScale" - выбранные графики автоматом вписываются по Y. И также "Custom Scale" число, отображается в списке графиков. Напр если юзер установил Custom Scale = 2, то данный график будет рисоваться в 2 раза больше по Y (чтобы быть соразмеримым с остальными)


Название: Re: Масштабирование и прокрутка графиков по отдельности
Отправлено: Bolonat от Август 22, 2017, 13:46
Так для QOpenGlWidget нужно resizeGL (а не resizeEvent)
Само собой! Оно присутствует в каждом QOpenGlWidget... Но без resizeEvent для окна-контейнера  при масштабировании изображение остается прямоугольником в центре, а по краям образуются пустые поля(Это поскольку виджеты элементы сцены, они не масштабируются автоматически).

Цитировать
Рисуете каждый график в своем буфере (QImage), а потом шлепаете все буфера в окно. А если с OpenGL то лучше использовать VBO (по сути тоже буфер)
Также графики могут иметь разный иасштаб по Y. Стандартные решения: опция "AutoScale" - выбранные графики автоматом вписываются по Y. И также "Custom Scale" число, отображается в списке графиков. Напр если юзер установил Custom Scale = 2, то данный график будет рисоваться в 2 раза больше по Y (чтобы быть соразмеримым с остальными)
Спасибо, покопаю в эту сторону...

Если убрать сцену, граф. представление, resizeEvent и просто положить QOpenGLWidget с QLayout на форму, то ведет себя лучше при масштабировании.


Название: Re: Масштабирование и прокрутка графиков по отдельности
Отправлено: Igors от Август 22, 2017, 14:28
Это поскольку виджеты элементы сцены, они не масштабируются автоматически
Ну вот со сценой/айтемами и разбирайтесь. Кстати не вижу зачем она здесь.


Название: Re: Масштабирование и прокрутка графиков по отдельности
Отправлено: Bolonat от Август 22, 2017, 14:40
Если бы с самого начала направили в нужное русло, не пришлось бы всякую ерунду городить...


Название: Re: Масштабирование и прокрутка графиков по отдельности
Отправлено: kuzulis от Август 23, 2017, 11:57
А пчму бы просто Qwt не использовать?


Название: Re: Масштабирование и прокрутка графиков по отдельности
Отправлено: Bolonat от Август 24, 2017, 07:12
А пчму бы просто Qwt не использовать?
Лицензия не подходит. Нужна LGPL. Да и медленная она...


Название: Re: Масштабирование и прокрутка графиков по отдельности
Отправлено: kuzulis от Август 24, 2017, 11:22
Цитировать
цензия не подходит. Нужна LGPL

http://qwt.sourceforge.net/qwtlicense.html

LOL, А там что, не LGPL с поблажками?

Цитировать
Да и медленная она...

LOOOL!  ;D



Название: Re: Масштабирование и прокрутка графиков по отдельности
Отправлено: Bolonat от Август 24, 2017, 13:11

Цитировать
LOOOL!  ;D
Ну, например (http://www.forum.crossplatform.ru/lofiversion/index.php/t4090.html)





Название: Re: Масштабирование и прокрутка графиков по отдельности
Отправлено: deMax от Август 24, 2017, 14:20
То есть, считаете, перерисовать 30 графиков с 200 тыс точек в каждом при изменении одного, это нормально?
200'000 точек в графике, но ведь они на мониторе тупо не поместятся.

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


Название: Re: Масштабирование и прокрутка графиков по отдельности
Отправлено: Bolonat от Август 24, 2017, 15:44
200'000 точек в графике, но ведь они на мониторе тупо не поместятся.
В настоящее время я никак не интерполирую значения. Тупо делю ширину на количество точек, получаю шаг (очень маленький), прибавляю его к текущему значению х  и отображаю.  
Соглашусь, что на одном пикселе может отобразиться тысяча значений, но зато я точно не потеряю данные.  То есть не будет искажений, который неизбежно появятся, если я буду отображать одну точку из ста (процеживание) или брать среднее из сотни точек или еще что-то.

Цитировать
Есть Qt Charts там лицензия конечно не айс, но вроде тяжелые графики тянул.
Лицензия на Qt Charts не подходит. Единственная библиотека, лицензия которой могла бы подойти это mathGL( да и то там есть ограничения) и производительность у нее хорошая. Но очень мало  материалов по ней в сети, а если задаешь вопросы в группе (в google+ по ней есть группа), то во-первых надо на английском, во-вторых очень медленный отклик. Русскоязычных форумов нет.


Название: Re: Масштабирование и прокрутка графиков по отдельности
Отправлено: deMax от Август 25, 2017, 08:08
В настоящее время я никак не интерполирую значения. Тупо делю ширину на количество точек, получаю шаг (очень маленький), прибавляю его к текущему значению х  и отображаю. 
Соглашусь, что на одном пикселе может отобразиться тысяча значений, но зато я точно не потеряю данные.  То есть не будет искажений, который неизбежно появятся, если я буду отображать одну точку из ста (процеживание) или брать среднее из сотни точек или еще что-то.
Ну вообще то вы находите для каждого экранного X координаты Y_MIN, Y_MAX, Y_IN, Y_OUT и не надо экран долбать постоянно


Название: Re: Масштабирование и прокрутка графиков по отдельности
Отправлено: Bolonat от Август 25, 2017, 09:07
Ну вообще то вы находите для каждого экранного X координаты Y_MIN, Y_MAX, Y_IN, Y_OUT и не надо экран долбать постоянно
Спасибо. А что такое  Y_IN, Y_OUT?


Название: Re: Масштабирование и прокрутка графиков по отдельности
Отправлено: deMax от Август 25, 2017, 10:24
Спасибо. А что такое  Y_IN, Y_OUT?
я ошибся, думал как входная и выходная точка, вы соединяете следующий Y_IN c предыдущим Y_OUT, и рисуете 2 линии (Y_IN(x+1) - Y_OUT(x) и Y_MIN - Y_MAX). Но это только шум даст и неверные данные(если Y_OUT почти вверху и Y_IN почти вверху он нарисует линию выше Y_MAX).
поэтому смотрите если у вас в dx (1 пиксель) влезает больше 1-1,5-2-3 точек, рисуете линии Y_MIN Y_MAX иначе обычный график.


Название: Re: Масштабирование и прокрутка графиков по отдельности
Отправлено: Bolonat от Август 25, 2017, 11:19
поэтому смотрите если у вас в dx (1 пиксель) влезает больше 1-1,5-2-3 точек, рисуете линии Y_MIN Y_MAX иначе обычный график.
Ок.