【问题标题】:How to fix "index < m_series->count()" error in xychart.cpp?如何修复 xychart.cpp 中的“index < m_series->count()”错误?
【发布时间】:2018-10-27 19:45:23
【问题描述】:

我开始在我的应用程序中使用QtCharts。我正在考虑的图表是折线图,使用对象QChartQLineSeries。由于所有点都是动态添加的,所以我使用信号/槽系统来更新图表:

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);
}

serieQLineSeries 对象)中添加点时调用函数onPointAdded。我给出的代码 sn-p 删除了serie 中的第一个点,例如图中的点数始终是固定的(开头除外)。

当我在Release 中运行这段代码时,没有问题。但是,当我在Debug 上运行它并且点数达到阈值时,我收到以下错误消息:

此对话框不会停止程序,但每次添加一个点(并达到阈值)时,都会在前一个对话框的顶部出现一个新对话框。

以下是重现错误的最少代码:

ma​​inwindow.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

ma​​inwindow.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 和一个QPushButton(用于动态添加点)。

我的 Qt 版本是 5.11.2,并且该错误是使用 MSVC 2017 64-bits 产生的。使用QChartQChartViewQLineSeries需要插件QtCharts

我想知道是否可以解决此问题或禁用 Qt 调试对话框消息。

【问题讨论】:

  • 很抱歉我给出的代码示例,无法重现代码。我编辑了帖子以添加我的项目的简化版本(我运行了这些文件,出现了消息框)。我希望这次更新会有所帮助。
  • 因此,mcve 确实有助于追查问题。 ;)

标签: c++ qt qtcharts qdebug


【解决方案1】:

原因

这不是错误,而是插槽MainWindow::onPointAdded(在您的代码中)和XYChart::handlePointAdded 执行顺序的预期结果。这是整个故事:

从错误消息中可以清楚地看出,在文件 xychart.cpp 的第 142 行中,indexm_series 计数的检查失败。使支票无效的是您的serie-&gt;remove(0);。原因是您的插槽执行检查的插槽之前执行,因为您的 connect 语句首先出现。问题是:首先到什么?好吧,这是棘手的部分,我不得不承认它确实不是立即显而易见的。但是,通过对源代码进行一些挖掘,可以找到问题的根源。路径如下:

  • 您的代码中的chart = new QChart; 实例化了一个QChart,而instantiates 又是一个PIMPL QChartPrivate

  • QChartPrivateconnects in it's constructorChartDataSet::seriesAddedChartPresenter::handleSeriesAdded

      QObject::connect(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), m_presenter, SLOT(handleSeriesAdded(QAbstractSeries*)));
    
  • 重要提示现在您将QLineSeries::pointAdded 连接到MainWindow::onPointAdded

  • 您代码中的chart-&gt;addSeries(serie); 导致ChartPresenter::handleSeriesAdded 槽被执行,其中QLineSeriesPrivate::initializeGraphics 被调用:

      series->d_ptr->initializeGraphics(rootItem());
    
  • QLineSeriesPrivate::initializeGraphics 中,LineChartItem 被实例化:

      LineChartItem *line = new LineChartItem(q,parent);
    
  • LineChartItemcalls其基类的构造函数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);

【讨论】:

    猜你喜欢
    • 2022-01-07
    • 2017-12-15
    • 2016-09-10
    • 2011-02-27
    • 2017-01-20
    • 1970-01-01
    • 2019-11-26
    • 1970-01-01
    • 2021-08-11
    相关资源
    最近更新 更多