Search code examples
c++qtqmlqt4.8

How to repaint QWidget encapsulated in QDeclarativeItem in QML?


I work in a C++/QML environment and I use Qt 4.8 with QtQuick 1.0.

I have a QWidget derivated class, QCustomPlot, and I encapsulated it in a custom QDeclarativeItem derived class. I use a QGraphicsProxyWidget to embed the QWidget, and it appears nicely upon creation. I would like to update the chart periodically, but I simply cannot, no matter what I do it stays however I initiated it in the constructor.

Here is the code (somewhat simplified) I have:

flowgrafik.h:

class FlowGrafik : public QDeclarativeItem
{
    Q_OBJECT
public:
    explicit FlowGrafik(QDeclarativeItem *parent = 0);
    ~FlowGrafik();

    void addFlow(double flow);

signals:

public slots:

private:
    QCustomPlot * customPlot;
    QGraphicsProxyWidget * proxy;
    QVector<double> x, y;

};

flowgrafik.cpp:

FlowGrafik::FlowGrafik(QDeclarativeItem *parent) : QDeclarativeItem(parent)
{
    customPlot = new QCustomPlot();
    proxy = new QGraphicsProxyWidget(this);
    proxy->setWidget(customPlot);
    this->setFlag(QGraphicsItem::ItemHasNoContents, false);
    customPlot->setGeometry(0,0,200,200);

    /* WHAT I WRITE HERE WILL BE DISPLAYED */

    // pass data points to graph:
    customPlot->graph(0)->setData(x, y);

    customPlot->replot();


}

FlowGrafik::~FlowGrafik()
{
    delete customPlot;
}

void FlowGrafik::addFlow(double flow)
{
    //THIS PART DOES NOT GET DISPLAYED
    for (int i=0; i<99; ++i)
    {
      y[i] = y[i+1];
    }
    y[99] = flow;
    customPlot->graph(0)->setData(x, y);
    customPlot->replot();
    this->update();
}

mainview.qml:

Rectangle {
    id: flowGrafik
    objectName: "flowGrafik"
    x: 400
    y: 40
    width: 200
    height: 200
    radius: 10
    FlowGrafik {
        id: flowGrafikItem
    }
}

I would really appreciate if anyone could tell me why my QCustomPlot QWidget does not replot.


Solution

  • Eventually the solution was to create a pointer in the C++ code that points at the QML item.

    I accidentally created an other instance in the C++, modified that one, and expected the QML instance to change.

    QDeclarativeView mainView;
    mainView.setSource(QUrl("qrc:///qml/qml/mainview.qml"));
    Flowgrafik * flowGrafik = mainView.rootObject()->findChild<QObject*>(QString("flowGrafikItem"));
    //or if Flowgrafik was the main element: Flowgrafik * flowGrafik = mainView.rootObject();
    flowGrafik->addFlow(x);