Search code examples
c++qtqgraphicsviewqgraphicssceneqtcharts

How do I auto zoom a chart in Qt when window size change?


I create a chart with QChart & QGraphicsScene & QGraphicsView, but the chart does not auto zoom in or zoom out when window change. How could I do that? I don't there is any signal or slot in QChart, QGraphicsScene, or QGraphicsView class. I know I could use QChart & QChartView, but I want QChart & QGraphicsScene & QGraphicsView for some purpose. Here is my code for draw a chart:

void MainWindow::on_actionDraw_Sine_Chart_triggered()
{
    QSplineSeries *spline = new QSplineSeries;

    for (double x = -M_PI; x < M_PI; x += 0.01) {
        spline->append(x, sin(x));
    }

    spline->setName(tr("Sine Curve"));    
    QChart *chart = new QChart;
    chart->addSeries(spline);
    chart->createDefaultAxes();
    chart->axisX()->setRange(-4, 4);
    chart->axisY()->setRange(-1.2, 1.2);
    chart->setGeometry(ui->graphicsView->rect());

    QGraphicsScene *scene = new QGraphicsScene;
    scene->addItem(chart);
    ui->graphicsView->setScene(scene);
}

Complete code is available here.


Solution

  • You have to track the size change of the viewport and change the size of the QChart, for that we use eventFilter, but since it is another method you need that chart is an attribute of the class.

    In addition to this it is not advisable to create the scene in the one slot, but in the constructor, the same with the QChart, and then only add the series.

    *.h

    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
        ...
        bool eventFilter(QObject *watched, QEvent *event); // +++
    private:
        Ui::MainWindow *ui;
        QChart *chart; // +++
        QGraphicsScene *scene; // +++
    };
    

    *.cpp

    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        scene = new QGraphicsScene;
        chart = new QChart;
        scene->addItem(chart);
        ui->graphicsView->setScene(scene);
        ui->graphicsView->viewport()->installEventFilter(this);
    
    }
    
    void MainWindow::on_actionDraw_Sine_Chart_triggered(){
        QSplineSeries *spline = new QSplineSeries;
    
        for (double x = -M_PI; x < M_PI; x += 0.01) {
            spline->append(x, sin(x));
        }
        spline->setName(tr("Sine Curve"));
        chart->addSeries(spline);
    }
    
    
    bool MainWindow::eventFilter(QObject *watched, QEvent *event)
    {
        if(watched == ui->graphicsView->viewport() && event->type() == QEvent::Resize){
            if(chart)
                chart->resize(ui->graphicsView->viewport()->size());
        }
        return QMainWindow::eventFilter(watched, event);
    }