Forum: PC-Programmierung C++, Qt, QChart updaten


von Vincent H. (vinci)


Lesenswert?

Grüß euch

Weiß zufällig jemand mit welch schwarzer Magie man ein QChart Objekt 
dazu bewegen kann doch bitte seine Daten upzudaten?

Folgendes ist mehr oder weniger das "LineChart example" auf der Qt 
Homepage:
https://doc.qt.io/qt-5/qtcharts-linechart-example.html
1
#include <qt/QtCharts/QtCharts>
2
#include <qt/QtWidgets/QApplication>
3
4
std::unique_ptr<QApplication> app;
5
6
int main(int argc, char* argv[]) {
7
  app = std::make_unique<QApplication>(argc, argv);
8
9
  QLineSeries* series = new QtCharts::QLineSeries();
10
  QList<QPointF> l;
11
  for (auto i{0}; i < 128; ++i)
12
    l.append({static_cast<qreal>(i), static_cast<qreal>(i)});
13
  series->append(l);
14
15
  QChart* chart{new QChart()};
16
  chart->legend()->hide();
17
  chart->addSeries(series);
18
  chart->createDefaultAxes();
19
  chart->setTitle("Simple line chart example");
20
21
  QChartView* chartView = new QChartView(chart);
22
  chartView->setRenderHint(QPainter::Antialiasing);
23
24
  QMainWindow window;
25
  window.setCentralWidget(chartView);
26
  window.resize(400, 300);
27
  window.show();
28
29
  auto vec = series->pointsVector();
30
  vec[42] = QPointF{5.0f, 5.0f};
31
  series->replace(vec);
32
33
  chartView->repaint();
34
  chartView->update();
35
  chartView->chart()->update();
36
  chartView->chart()->setTitle("FUCK");
37
38
  return app->exec();
39
}

Mittels replace Methode von QLineSeries tausche ich den 42. Datenpunkt 
gegen {5, 5} aus. Aus irgendeinem Grund tut sich dabei allerdings 
nichts. Was interessanterweise schon funktioniert ist den Titel zu 
ändern... ("FUCK").

repaint(), update() und chart->update() ändern auch nichts. WTF?!

von René H. (Firma: anonymous) (hb9frh)


Lesenswert?


von Sven B. (scummos)


Lesenswert?

Hm, sehe nach kurzem Schauen keinen Fehler. Füge mal die Series noch ein 
zweites Mal mit addSeries hinzu, tut sich dann was? Ich denke der Fehler 
ist nicht, dass nicht repainted wird, sondern was anderes.

Du musst auch bedenken, dass vor app->exec() überhaupt nix gepainted 
wird, das passiert immer nur, wenn ein PaintEvent kommt -- und das 
wiederum passiert sicherlich nicht, bevor das Fenster aufgeht. Der Code 
müsste sich also gleich verhalten, wenn du alle repaint / update-Aufrufe 
rauswirfst.

Ich muss allerdings auch sagen, dass ich eine Weile mit QCharts 
gearbeitet habe und kein Fan bin. Dafür gibt es 3 Gründe:

 - Die API ist verwirrender, als sie es sein müsste. Mit dem 
QGraphicsView gibt es irgendwie drei oder sogar vier relevante 
Koordinatensysteme (die GraphicsView-Koordinaten, die Daten-Koordinaten, 
die Pixel-Koordinaten, ...). So viele bräuchte man nicht. Das mit den 
Achsen hätte man auch eleganter lösen können, weil >95% der Anwendungen 
immer nur ein Paar Achsen hat. Viele andere Dinge könnten auch wirklich 
einfacher sein. Und besonders umfangreich ist sie auch nicht. Update: 
Haha, ich sehe, der erste Poster in dem verlinkten Thread ist derselben 
Meinung.

 - Die Qualität der erzeugten Plots ist bestenfalls mäßig. Sinnvolle 
automatische Achsenskalierung? Fehlanzeige. Sinnvolle Anzeige von Labels 
auf den Achsen? Sicher nicht. Sinnvolle Ticks? Nö. Verglichen mit dem, 
was z.B. Qwt oder matplotlib tun ist das ein Witz.

 - Anders als der Großteil von Qt ist das Modul GPL, was strenge 
Auflagen für darauf basierende Software zur Folge hat.

Mein Rat: wenn du nicht nur 3 Punkte malen willst, nimm lieber gleich 
Qwt. Die API ist zwar manchmal etwas over-engineered, aber insgesamt ist 
das ein viel ernstzunehmenderes Projekt. QtCharts ist ein schnell 
zusammengehacktes Hipster-Modul, was an Geschäftskunden verkauft werden 
soll, die in ihrer Qt Smartphone-App einen Aktienkurs rendern wollen.

: Bearbeitet durch User
von Vincent H. (vinci)


Lesenswert?

Ich check die komplette API irgendwie nicht.


Folgendes etwa ändert die series und schiebt den ganzen Plot um "50" 
ticks nach rechts:
1
  l.clear();
2
  series->clear();
3
  for (auto i{0}; i < 128; ++i)
4
    l.append({static_cast<qreal>(i + 50), static_cast<qreal>(i)});
5
  series->append(l);

Folgendes ändert gar nichts:
1
  l.clear();
2
  series->clear();
3
  for (auto i{0}; i < 128; ++i)
4
    l.append({static_cast<qreal>(i), static_cast<qreal>(i)});
5
  l.replace(42, {5.0f, 5.0f});
6
  series->append(l);

WTF? Das heißt ein List::replace macht keinen replace...?

von mr. mo (Gast)


Lesenswert?

Vincent H. schrieb:
> WTF?!

Jop! Bin das gleiche Tal durch. Kann mich nur leider nicht mehr an die 
konkrete Lösung erinnern, find auch kein altes Backup vom damaligen 
Projekt.

Ich kann mich aber erinnern, dass QChart auch total langsam ist und 
irgendwie "altmodisch" aussieht.

Seitdem verwende ich nur noch QCustomPlot [1]. Doku ist super und die 
Plots funktionieren sehr gut, schnell und zuverlässig.
Kann ich wärmstens empfehlen!

[1] https://www.qcustomplot.com/

von Sven B. (scummos)


Lesenswert?

QCustomPlot ist auch prima, wenn für das Projekt die GPL kein Problem 
ist. Aber die API und das Rendering ist in Ordnung.

von Vincent H. (vinci)


Lesenswert?

Bin nach dem Abendessen auf qwt umgestiegen und binnen 15min war die 
Sache erledigt...

Danke!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.