如何修复 xychart.cpp 中的 "index < m_series->count()" 错误?
How to fix "index < m_series->count()" error in xychart.cpp?
我开始使用QtCharts
in my application. The chart that I am considering is a Line Chart, using the objects QChart
and QLineSeries
。由于所有点都是动态添加的,我使用signal/slot系统更新图表:
QLineSeries* serie = new QLineSeries(this);
connect(serie, SIGNAL(pointAdded(int)), this, SLOT(onPointAdded(int)));
void MyChart::onPointAdded(int index) {
// Delete the first items if the number of points has reached a threshold
while (serie->points().length() >= threshold)
serie->remove(0);
}
在serie
(一个QLineSeries
对象)中添加一个点时调用函数onPointAdded
。我给出的代码片段删除了 serie
中的第一个点,例如图中的点数始终是固定的(开头除外)。
当我运行这段代码在Release
时,没有问题。但是,当我 运行 它在 Debug
并且点数达到阈值时,我收到以下错误消息:
此对话框不会停止程序,但每次添加一个点(并达到阈值)时,都会在前一个对话框之上出现一个新对话框。
以下是重现错误的最少代码:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QChart>
#include <QLineSeries>
#include <QMainWindow>
#include <QValueAxis>
#include <QtCharts/QChart>
#include <QtCharts/QLineSeries>
QT_CHARTS_USE_NAMESPACE
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
QChart* chart = nullptr;
QLineSeries* serie = nullptr;
int threshold = 5;
private slots:
void onAddPointButtonClicked();
void onPointAdded(int index);
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), ui(new Ui::MainWindow) {
ui->setupUi(this);
chart = new QChart;
serie = new QLineSeries(this);
connect(ui->bt_addPoint, SIGNAL(clicked()), this, SLOT(onAddPointButtonClicked()));
connect(serie, SIGNAL(pointAdded(int)), this, SLOT(onPointAdded(int)));
chart->legend()->hide();
chart->addSeries(serie);
ui->graphicsView->setChart(chart);
}
MainWindow::~MainWindow() {
delete ui;
}
void MainWindow::onAddPointButtonClicked() {
serie->append(0, 1);
}
void MainWindow::onPointAdded(int index) {
while (serie->points().length() >= threshold)
serie->remove(0);
}
我使用了一个UI表单来生成图形界面。该接口包含一个QChartView
and a QPushButton
(动态添加点数)。
我的Qt版本是5.11.2,bug是用MSVC 2017 64-bits产生的。插件 QtCharts 需要使用 QChart
, QChartView
和QLineSeries
.
我想知道是否可以解决此问题或禁用 Qt 调试对话框消息。
原因
这不是错误,而是插槽 MainWindow::onPointAdded
(在您的代码中)和 XYChart::handlePointAdded
执行顺序的预期结果。这是整个故事:
从错误消息中可以清楚地看出,在文件 xychart.cpp
的第 142 行,index
与 m_series
的计数检查失败。使支票无效的是你的 serie->remove(0);
。原因是您的插槽在 之前 进行检查的插槽执行,因为您的 connect
语句首先出现。问题是:首先要什么?好吧,这是棘手的部分,我不得不承认它确实不是很明显。然而,通过深入挖掘源代码,可以找到问题的根源。路径如下:
chart = new QChart;
在你的代码中实例化了一个 QChart
,它又 instantiates 一个 PIMPL QChartPrivate
QChartPrivate
connects in it's constructor ChartDataSet::seriesAdded
到 ChartPresenter::handleSeriesAdded
:
QObject::connect(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), m_presenter, SLOT(handleSeriesAdded(QAbstractSeries*)));
重要 现在您将 QLineSeries::pointAdded
连接到 MainWindow::onPointAdded
chart->addSeries(serie);
在您的代码中导致 ChartPresenter::handleSeriesAdded
槽被执行,其中 QLineSeriesPrivate::initializeGraphics
被调用:
series->d_ptr->initializeGraphics(rootItem());
在QLineSeriesPrivate::initializeGraphics
中实例化了一个LineChartItem
:
LineChartItem *line = new LineChartItem(q,parent);
LineChartItem
calls其基class的构造函数XYChart
其自身构造函数
的初始化列表
重要 只是现在是 connect
语句 executed,这会给你带来麻烦 XYChart::handlePointAdded
插槽当一个点被添加到系列时被调用:
QObject::connect(series, SIGNAL(pointAdded(int)), this, SLOT(handlePointAdded(int)));
只关注标记为重要的步骤,两个 connect
语句的顺序就很明显了。这也是调用各个插槽的顺序。
解决方案
考虑到这个原因,我建议您先将系列添加到图表中,然后然后连接pointAdded
信号,即:
移动
connect(serie, SIGNAL(pointAdded(int)), this, SLOT(onPointAdded(int)));
任何地方在
之后
chart->addSeries(serie);
我开始使用QtCharts
in my application. The chart that I am considering is a Line Chart, using the objects QChart
and QLineSeries
。由于所有点都是动态添加的,我使用signal/slot系统更新图表:
QLineSeries* serie = new QLineSeries(this);
connect(serie, SIGNAL(pointAdded(int)), this, SLOT(onPointAdded(int)));
void MyChart::onPointAdded(int index) {
// Delete the first items if the number of points has reached a threshold
while (serie->points().length() >= threshold)
serie->remove(0);
}
在serie
(一个QLineSeries
对象)中添加一个点时调用函数onPointAdded
。我给出的代码片段删除了 serie
中的第一个点,例如图中的点数始终是固定的(开头除外)。
当我运行这段代码在Release
时,没有问题。但是,当我 运行 它在 Debug
并且点数达到阈值时,我收到以下错误消息:
此对话框不会停止程序,但每次添加一个点(并达到阈值)时,都会在前一个对话框之上出现一个新对话框。
以下是重现错误的最少代码:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QChart>
#include <QLineSeries>
#include <QMainWindow>
#include <QValueAxis>
#include <QtCharts/QChart>
#include <QtCharts/QLineSeries>
QT_CHARTS_USE_NAMESPACE
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
QChart* chart = nullptr;
QLineSeries* serie = nullptr;
int threshold = 5;
private slots:
void onAddPointButtonClicked();
void onPointAdded(int index);
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), ui(new Ui::MainWindow) {
ui->setupUi(this);
chart = new QChart;
serie = new QLineSeries(this);
connect(ui->bt_addPoint, SIGNAL(clicked()), this, SLOT(onAddPointButtonClicked()));
connect(serie, SIGNAL(pointAdded(int)), this, SLOT(onPointAdded(int)));
chart->legend()->hide();
chart->addSeries(serie);
ui->graphicsView->setChart(chart);
}
MainWindow::~MainWindow() {
delete ui;
}
void MainWindow::onAddPointButtonClicked() {
serie->append(0, 1);
}
void MainWindow::onPointAdded(int index) {
while (serie->points().length() >= threshold)
serie->remove(0);
}
我使用了一个UI表单来生成图形界面。该接口包含一个QChartView
and a QPushButton
(动态添加点数)。
我的Qt版本是5.11.2,bug是用MSVC 2017 64-bits产生的。插件 QtCharts 需要使用 QChart
, QChartView
和QLineSeries
.
我想知道是否可以解决此问题或禁用 Qt 调试对话框消息。
原因
这不是错误,而是插槽 MainWindow::onPointAdded
(在您的代码中)和 XYChart::handlePointAdded
执行顺序的预期结果。这是整个故事:
从错误消息中可以清楚地看出,在文件 xychart.cpp
的第 142 行,index
与 m_series
的计数检查失败。使支票无效的是你的 serie->remove(0);
。原因是您的插槽在 之前 进行检查的插槽执行,因为您的 connect
语句首先出现。问题是:首先要什么?好吧,这是棘手的部分,我不得不承认它确实不是很明显。然而,通过深入挖掘源代码,可以找到问题的根源。路径如下:
chart = new QChart;
在你的代码中实例化了一个QChart
,它又 instantiates 一个 PIMPLQChartPrivate
QChartPrivate
connects in it's constructorChartDataSet::seriesAdded
到ChartPresenter::handleSeriesAdded
:QObject::connect(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), m_presenter, SLOT(handleSeriesAdded(QAbstractSeries*)));
重要 现在您将
QLineSeries::pointAdded
连接到MainWindow::onPointAdded
chart->addSeries(serie);
在您的代码中导致ChartPresenter::handleSeriesAdded
槽被执行,其中QLineSeriesPrivate::initializeGraphics
被调用:series->d_ptr->initializeGraphics(rootItem());
在
QLineSeriesPrivate::initializeGraphics
中实例化了一个LineChartItem
:LineChartItem *line = new LineChartItem(q,parent);
的初始化列表LineChartItem
calls其基class的构造函数XYChart
其自身构造函数重要 只是现在是
connect
语句 executed,这会给你带来麻烦XYChart::handlePointAdded
插槽当一个点被添加到系列时被调用:QObject::connect(series, SIGNAL(pointAdded(int)), this, SLOT(handlePointAdded(int)));
只关注标记为重要的步骤,两个 connect
语句的顺序就很明显了。这也是调用各个插槽的顺序。
解决方案
考虑到这个原因,我建议您先将系列添加到图表中,然后然后连接pointAdded
信号,即:
移动
connect(serie, SIGNAL(pointAdded(int)), this, SLOT(onPointAdded(int)));
任何地方在
之后chart->addSeries(serie);