Qt Chart Series удаляет не показанные сбои данных

Я пытаюсь создать класс графического графика в реальном времени в qt, и прокрутка работает. Но при просмотре моей программы в диспетчере задач я понял, что использование ЦП и ОЗУ увеличивается со временем (и данными).

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

void Live_Chart::UpdateY(float yValue)
{
xValue++;
this->yValue = yValue;
m_series->append(xValue, yValue);

if (xValue > m_axisX->max())
{
    // "Scroll" the data in the view
    m_axisX->setMax(xValue);
    m_axisX->setMin(m_axisX->min()+1);

    // Remove the previous data we don't see
    qDebug() << "Removing " << m_axisX->min();
    m_series->remove(m_axisX->min());
}
}

Этот метод вызывается каждые 100 мс со случайным числом от 0 до 10.

Но всегда при достижении remove=52 программа вылетает с этим сообщением об ошибке:

ASSERT failure in QVector<T>::remove: "index out of range", file c:\users\qt\work\qt\qtbase\include\qtcore\../../src/corelib/tools/qvector.h, line 483

И я действительно понятия не имею, почему 52. Это число не указано ни в одной части моей программы. Диапазон оси X равен 50. При создании QLineSeries я добавляю точку (0, 0).

РЕДАКТИРОВАТЬ: при использовании диапазона m_axisX (0, 20) программа аварийно завершает работу при попытке удалить точку 22.

--› Программа вылетает при удалении точки с x=x-range+2 (Проверено и с другими числами).


person 532465747    schedule 31.03.2021    source источник
comment
можете ли вы опубликовать минимально воспроизводимый пример?   -  person 463035818_is_not_a_number    schedule 31.03.2021
comment
Я не знаю, чем репрекс может отличаться от моей программы, может быть, моя правка поможет?   -  person 532465747    schedule 31.03.2021
comment
QVector::remove принимает индекс удаляемого элемента. Неясно, как m_series->remove(m_axisX->min());, а затем увеличение min и повторный вызов m_series->remove(m_axisX->min()); должны работать правильно. Предположим, что старый min равен 42, вы удаляете элемент с индексом 42, тогда почему при следующем вызове вы хотите удалить элемент с индексом 43?   -  person 463035818_is_not_a_number    schedule 31.03.2021
comment
Какой тип m_axisX?   -  person G.M.    schedule 31.03.2021
comment
как репрекс может отличаться от моей программы - нет информации о типах, задействованных в опубликованном вами коде. Только из ошибки я смог узнать, что это QVector. ПОЖАЛУЙСТА, прочитайте минимально воспроизводимый пример. Код, который вы разместили, может быть правильным или нет, в зависимости от кода, который вы не опубликовали.   -  person 463035818_is_not_a_number    schedule 31.03.2021
comment
При каждом вызове график прокручивается влево, поэтому крайняя левая точка не отображается. Вот этот момент я хочу удалить. Поэтому, конечно, при следующем вызове это число увеличивается, потому что увеличивается мое значение xValue.   -  person 532465747    schedule 31.03.2021
comment
@G.M. QValueAxis   -  person 532465747    schedule 31.03.2021
comment
m_series содержит все точки данных? Если вы двигаетесь влево, я ожидаю, что вы всегда удаляете первый элемент. Почему индекс удаляемого элемента определяется текущим значением оси min ?   -  person 463035818_is_not_a_number    schedule 31.03.2021
comment
я имею в виду, что я не понимаю, что если я вызываю эту функцию много раз, то при каждом вызове вы добавляете один элемент в m_series и удаляете из него один элемент, т.е. количество элементов остается прежним, но индекс, который вы хотите удалить, увеличивается неограничен, поэтому вполне естественно, что в какой-то момент он выйдет за пределы. Что мне не хватает? Есть ли какой-то код, который добавляет больше элементов в вектор? Ось min где-то уменьшилась?   -  person 463035818_is_not_a_number    schedule 31.03.2021
comment
я предполагаю, что в случае диапазона m_axisX (0, 20) программа вылетает при попытке удалить точку 22. вы начинаете с вектора из 21 элемента, затем вместо удаления самого старого элемента с индексом 0 вы удаляете элемент по индексу m_axis.min() и поскольку min увеличивается с шагом 1, но вектор имеет только 21 элемент, вы не можете стереть элемент с индексом 22. Это просто предположение, но я думаю, вам просто нужно m_series->remove(0);   -  person 463035818_is_not_a_number    schedule 31.03.2021
comment
@largest_prime_is_463035818 О, хорошо, теперь я понимаю, проблема может быть в этом. Итак, когда позже в программе минимум m_axisX равен 43, индекс этой первой точки по-прежнему равен 0, тогда как я думал, что он будет 43, верно? (Что не имело бы никакого смысла...) Так что я должен всегда удалять индекс 0, верно?   -  person 532465747    schedule 31.03.2021
comment
О, хорошо, вы нашли решение раньше меня. Я не увидела ваш комментарий, когда писала свой ;)   -  person 532465747    schedule 31.03.2021
comment
Я написал ответ, но учтите, что на самом деле я не могу сказать вам, правильный ли мой ответ. Только вы можете знать, хотите ли вы стереть элемент с индексом 0 или элемент с индексом m_axisX->min(), код слишком неполный, чтобы я мог его понять, хотя, если вы также не можете объяснить, почему это должен быть элемент с индексом min, тогда мое предположение наверное правильно ;)   -  person 463035818_is_not_a_number    schedule 31.03.2021


Ответы (1)


Вы путаете индекс точек данных в векторе m_series и их значение x. Когда точка данных с x = old_x_min выходит за пределы окна, которое вы хотите отобразить, тогда эта точка данных находится в индексе 0, а не в индексе old_x_min.

Заменять

m_series->remove(m_axisX->min());

с

m_series->remove(0);

чтобы удалить самую старую точку данных вместо некоторой точки данных в середине ряда.

person 463035818_is_not_a_number    schedule 31.03.2021
comment
Эй, просто хотел сказать, что удаление точек действительно сильно влияет на производительность. При работе до x=3000 это больше минуты! - person 532465747; 31.03.2021