Search code examples
c++qtqt5qt-signalsqtcharts

Qt How to connect the rubberBandChanged signal


I try to link the rubberBandChanged signal from QChartView class to a specific function in MainWindow class.

MainWindow.h

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

public slots:
    void rubberZoomAdapt(QRect, QPointF, QPointF);

private:
    Ui::MainWindow *ui;
    QChartView* qcvChart;
    Chart* chart;
};

MainWindow.cpp

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    qcvChart(new QChartView),
    chart(new Chart)
{
    ui->setupUi(this);

    //Connexion
    QObject::connect(qobject_cast<QGraphicsView*>(this->qcvChart),
                     &QGraphicsView::rubberBandChanged,
                     this,
                     &MainWindow::rubberZoomAdapt);

    this->qcvChart->setChart(this->chart);
    this->qcvChart->setRubberBand(QChartView::HorizontalRubberBand);
}

void MainWindow::rubberZoomAdapt(QRect r, QPointF fp, QPointF tp)
{
    static int i = 0;
    qDebug() << "(rubberZoomAdapt) RubberBand Event: " << QString::number(i++);
}

When I use the rubberBand in my chart, I never enter in the rubberZoomAdapt().

Any idee to fix this ?

Thanks.


Solution

  • The problem is that although QChartView inherits from QGraphicsView it does not use the same QRubberBand so the rubberBandChanged signal is never issued.

    The solution is to look for the QRubberBand since it is a child of QChartView and filter it through the resizeEvent event, and then create our own signal:

    *.h

    ...
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
        bool eventFilter(QObject *watched, QEvent *event) override;
    public slots:
        void rubberZoomAdapt(QPointF fp, QPointF tp);
    
    signals:
        void rubberBandChanged(QPointF fp, QPointF tp);
    
    private:
        Ui::MainWindow *ui;
        QChartView* qcvChart;
        QChart* chart;
        QRubberBand *rubberBand;
    };
    ...
    

    *.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    #include <QDebug>
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow),
        qcvChart(new QChartView),
        chart(new QChart)
    {
        ui->setupUi(this);
    
        qcvChart->setChart(chart);
        qcvChart->setRubberBand(QChartView::HorizontalRubberBand);
        rubberBand = qcvChart->findChild<QRubberBand *>();
        rubberBand->installEventFilter(this);
    
        connect(this, &MainWindow::rubberBandChanged,this, &MainWindow::rubberZoomAdapt);
    
        setCentralWidget(qcvChart);
        ...
    }
    
    ...
    
    bool MainWindow::eventFilter(QObject *watched, QEvent *event)
    {
        if(watched == rubberBand && event->type() == QEvent::Resize){
            QPointF fp = chart->mapToValue(rubberBand->geometry().topLeft());
            QPointF tp = chart->mapToValue(rubberBand->geometry().bottomRight());
            emit rubberBandChanged(fp, tp);
        }
        return QMainWindow::eventFilter(watched, event);
    }
    
    void MainWindow::rubberZoomAdapt(QPointF fp, QPointF tp)
    {
        qDebug() << "(rubberZoomAdapt) RubberBand Event: "<<fp<<tp;
    }
    

    The complete example can be found in the following link