Как создать диаграмму в QML с данными о сериях из C++
Я заполняю QLineSeries
данные на стороне C++ и QML-диаграмма должны их потреблять (и обновлять по мере их изменения). Производитель данных подключен к newData
которые добавляются к данным серии, и это должно вызвать перерисовку диаграммы.
Ранее LineSeries
манипулировали в QML, но теперь я не знаю, как сделать C++ QLineSeries
экземпляры, доступные для QML.
// ...
#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();
}
main.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);
}
*/
};
Есть ли хорошее решение для этого?
В крайнем случае, я также могу создать весь ChartView в C++ (но опять же, как вставить его в QML?).
1 ответ
Можно сказать, что LineSeries
это QLineSeries
+ другие функции, так ChartView
использует эти другие функции.
Что вы должны сделать, это получить доступ к LineSeries
в UiData
Для этого необходимо использовать позицию памяти.
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
,
Полный пример можно найти по следующей ссылке.