Как перекрасить QChart

Я хотел бы знать, как перекрасить QChart после того, как я добавляю новые пункты к QLineSeries добавил к этому.
Цель состоит в том, чтобы использовать это для отображения данных, получаемых с высокой скоростью (до 400 000 точек / сек), и обновления графика по мере поступления точек в пакетах.

Вот тестовая программа, над которой я работал:

MainWindow:

class MainWindow : public QMainWindow{
Q_OBJECT

QLineSeries *series;
QChart *chart;
QChartView *chartView;

int cnt=0;public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();

private slots:
void on_pB_Start_clicked();

private:
Ui::MainWindow *ui;
};

Конструктор MainWindow:

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow){
ui->setupUi(this);

series = new QLineSeries();

chart = new QChart();
chart->setBackgroundRoundness(0);

chart->addSeries(series);

// A bunch of formatting
chart->setBackgroundVisible(false);
chart->setMargins(QMargins(0,0,0,0));
chart->layout()->setContentsMargins(0,0,0,0);
chart->legend()->hide();
chart->setPlotAreaBackgroundBrush(QBrush(Qt::black));
chart->setPlotAreaBackgroundVisible(true);
chartView = new QChartView(chart);
ui->gridLayout->addWidget(chartView);

}

И кнопка clicked Событие для добавления очков в серию:

void MainWindow::on_pB_Start_clicked(){
series->append(cnt,qSin(cnt/10));
cnt++;
// Update plot here << ======== HOW?
}

Пример OpenGLSeries делает это как-то. Я не понимаю как. Но в этом случае все немного по-другому, поскольку он заменяет все точки в серии новыми, а не добавляет их.

5

Решение

Во-первых, если вы получите и добавите очки со скоростью 400000 очков / сек в потоке графического интерфейса, ваше приложение будет полностью заморожено. Таким образом, вам необходимо выделить другой поток для получения и обработки данных и отправить обработанные графические данные в поток GUI, используя (например) сигналы / слоты, связанные с QueuedConnection. Под «обработкой» я подразумеваю, по крайней мере, некоторую децимацию (усреднение, отбрасывание, децимацию, как это понимают те, кто занимается DSP), поскольку скорость 400000 pts / sec, скорее всего, приведет к потере памяти и производительности графического интерфейса. Но если вы не хотите уничтожать, это ваше дело. В этом случае вы можете рассмотреть более легкий механизм доставки данных, чем QueuedConnectionEd сигналы / слоты.

Второй вопрос: когда строить сюжет? Не так давно я реализовал похожую функциональность с QCustomPlot по гораздо более низким ставкам. Основная проблема, с которой я столкнулся, заключалась в огромном (и меняющемся) лаге, когда я пытался реплотировать после получения каждой точки, особенно при построении графика сглаживания. В вашем случае решение заключается в подклассе QChartView (Я полагаю, вы уже сделали это), переопределить timerEvent в это и звони startTimer()/killTimer() когда вам нужно начать / остановить реплоттинг. Кроме того, вы можете держать таймер в объекте, который владеет QChartView откладывание объектов и проблем оттуда, но это похоже на утечку абстракции по сравнению с подклассами QChartView, В целом, этот подход позволяет вам достичь почти постоянной частоты кадров и сделать ее настолько плавной, насколько вы хотите, без зависания интерфейса приложения.

И, наконец, как сделать реплот? QChartView кажется, имеет repaint() метод, унаследованный от QWidget который делает то, что вам нужно.

2

Другие решения

Видимо QCharts не нужен repaint(), Добавление новых пунктов к серии, кажется, достаточно. Я не видел данные, потому что я не установил ось для символа, а также потому, что значения не были правильно рассчитаны.

Исправленный код:

Заголовок:

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow){
ui->setupUi(this);

series = new QLineSeries();

chart = new QChart();
chart->addSeries(series);

chart->createDefaultAxes(); // Preparing the axis
chart->axisX()->setRange(0,10);
chart->axisY()->setRange(0,10);

// Same formatting
chart->setBackgroundVisible(false);
chart->setMargins(QMargins(0,0,0,0));
chart->layout()->setContentsMargins(0,0,0,0);
chart->legend()->hide();
chart->setPlotAreaBackgroundBrush(QBrush(Qt::black));
chart->setPlotAreaBackgroundVisible(true);
chartView = new QChartView(chart);
ui->gridLayout->addWidget(chartView);
}

И код кнопки, кастинг cnt удвоить до расчета.

void MainWindow::on_pB_Start_clicked(){
double val = 3*(qSin((double)cnt*2)+2);
series->append(cnt,val); // Enough to trigger repaint!
cnt++;
}
3

По вопросам рекламы [email protected]