c++ - 如何使用从 C++ 公开的系列数据在 QML 中创建图表

标签 c++ qml qtcharts

我正在 c++ 端填充 QLineSeries 数据,QML 图表应该使用它们(并随着它们的变化而更新)。数据生成器连接到添加到系列数据的 newData,这应该会触发图表的重绘。

以前,LineSeries 是在 QML 中操作的,但现在我不知道如何使 QML 可以访问 c++ QLineSeries 实例。

// ...
#include<QtCharts/QLineSeries>
using namespace QtCharts;

/* class holding all data to be displayed as properties */
class UiData: public QObject{
   Q_OBJECT
   Q_PROPERTY(QLineSeries *xy READ getXy NOTIFY xyChanged);
   QLineSeries* getXy(){return &xy; }
   signals:
      void xyChanged();
   public slots:
      void newData(float x, float y){
         xy.append(x,y);
         emit xyChanged();
      }
   private:
      QLineSeries xy;
}

int main(int argc, char* argv[]){
   QApplication app(argc,argv);
   QQmlApplicationEngine engine;
   UiData uiData;
   /* make the instance accessiblt from QML */
   engine.rootContext()->setContextProperty("uiData",&uiData);
   engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
   // ...
   return qApp->exec();
}

主.qml:

ChartView{
   ValueAxis{
      id: _axisX;
   }
   ValueAxis{
      id: _axisY;
   }
   /*
   BEFORE:
   data in QML: easy, plus had JS slot calling _xySeries.append(...)
   */
   LineSeries{
      id: _xySeries;
      axisX: _axisX;
      axisY: _axisY;
   }

   /*
   NOW:
   how to use an already existing LineSeries instance (uiData.xy),
   and only change a few attributes, like axisX and axisY?

   Something like this:

   LineSeries(uiData.xy) {
      axisX: _axisX;
      axisY: _axisY;
   }

   or like this:

   component.onCompleted:{
      // where is something like ChartView.addSeries?
      // (there is ChartView.removeSeries already)
      uiData.xy.axisX=_axisX;                    
      uiData.xy.axisY=_axisY;
      addSeries(uiData.xy);
   }
   */
};

有好的解决办法吗?

在极端情况下,我还可以用 C++ 创建整个 ChartView(但话又说回来,如何将它插入到 QML 中?)。

最佳答案

可以说 LineSeriesQLineSeries + 其他功能,所以 ChartView 使用了那些其他功能。

你必须做的是访问 UiData 中的 LineSeries,为此你必须使用内存位置。

class UiData: public QObject{
    Q_OBJECT
    Q_PROPERTY(QLineSeries* xy READ xy WRITE setXy NOTIFY xyChanged)
public:
    ...
    QLineSeries *xy() const
    {
        return mXy;
    }
    void setXy(QLineSeries *xy)
    {
        if(mXy == xy) return;
        if(mXy)
            if(mXy->parent() == this) // is owner
                delete mXy;
        mXy = xy;
        emit xyChanged();
    }
public slots:
    void newData(qreal x, qreal y){
        if(mXy){
            mXy->append(x, y);
        }
    }
    ...
signals:
    void xyChanged();
    ...
private:
    QLineSeries *mXy;
};

*.qml

ChartView{
    ValueAxis{
        id: _axisX;
    }
    ValueAxis{
        id: _axisY;
    }
    LineSeries{
        id: _xySeries;
        axisX: _axisX;
        axisY: _axisY;
    }
}
Component.onCompleted: uiData.xy = _xySeries // <----

如您所见,QLineSeries 并未在 C++ 中创建,但指针仅用于引用 LineSeries

完整的例子可以在下面的link中找到.

关于c++ - 如何使用从 C++ 公开的系列数据在 QML 中创建图表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51793635/

相关文章:

c++ - 使用鼠标滚轮缩放 QChartView 的 x 轴

c++ - 将 uint64 转换为 GMP/MPIR 编号

gridview - 在运行时更改 QML GridView 模型

c++ - 使用文件的 undefined reference

qt - 在运行时在多个 .qrc 文件之间切换

QML - 控制矩形元素任意一侧的边框宽度和颜色

c++ - Qt 图表条形图调整大小崩溃

python - 如何将 QTableWidget 中的数据绘制到 QChart 中

c++ - 从长到短的转换错误

c++ - 使用 VirtualDisk API 创建 VHD 文件