c++qtqt5qtchartsqchartview

QChartView QLineSeries select by mouse click


Unfortunately, I can't find any way to catch a signal of mouse click on any QLineSeries at QChartView. This is required for the subsequent increase in the thickness of the curve on the graph.


Solution

  • You can use the clicked signal of the QLineSeries and since it will affect the same series then you could create a derived class

    main.cpp

    #include <QApplication>
    #include <QChartView>
    #include <QLineSeries>
    #include <random>
    
    QT_CHARTS_USE_NAMESPACE
    
    class LineSeries: public QLineSeries{
    public:
        LineSeries(QObject *parent = nullptr):
            QLineSeries(parent)
        {
            connect(this, &QXYSeries::clicked, this, &LineSeries::onClicked);
        }
    private slots:
        void onClicked(){
            QPen p = pen();
            p.setWidth(p.width()+1);
            setPen(p);
        }
    };
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        QChart *chart = new QChart();
        chart->legend()->hide();
    
        chart->setTitle("Simple line chart example");
    
        std::random_device rd;     // only used once to initialise (seed) engine
        std::mt19937 rng(rd());
        std::uniform_int_distribution<int> uni(0, 10);
    
        for(size_t i=0; i< 5; i++){
            LineSeries *series = new LineSeries();
            for(size_t j=0; j < 10; j++){
                *series << QPointF(j, uni(rng));
            }
            chart->addSeries(series);
        }
        chart->createDefaultAxes();
    
        QChartView chartView(chart);
        chartView.setRenderHint(QPainter::Antialiasing);
        chartView.resize(640, 480);
        chartView.show();
    
        return a.exec();
    }
    

    enter image description here

    Update:

    you have to connect the series, you do not understand that it is ui-> vchrt but assume that it is a QChartView, but QChartView does not have the clicked signal so it seems strange to me that this code works, on the other hand:

    QLineSeries **series;
    series = new QLineSeries*[data.size()];
    

    is a bad practice in C ++, you are using the C style in C ++, you should use container as QList , for example:

    QList<QLineSeries *> series;
    
    for(size_t i=0; i< data.size(); i++){
        QLineSeries *serie = new QLineSeries();
        for(size_t j=0; j < 10; j++){
            *serie << QPointF(/*values*/);
        }
        series << serie;
        connect(serie, &QXYSeries::clicked, this, &MainWindow::on_series_Clicked);
        chart->addSeries(serie);
    }
    

    after that you must modify your slot, only the QObjects are passed the pointer, QPointF must be passed by value, but even so it is not necessary since you will not use that data, and as the one that emits the signal is the QLineSeries this is passed through sender() in the slot, with a casting we get the series and the changes are made.:

    *.h

    private slots:
        void on_series_Clicked();
    

    *.cpp

    void MainWindow::on_series_Clicked(){
        auto serie = qobject_cast<QLineSeries *>(sender());
        QPen p = serie->pen();
        p.setWidth( p.width() == 1 ? 5: 1);
        serie->setPen(p);
    }