Help us understand the problem. What is going on with this article?

Qt Quickで折れ線グラフ

More than 1 year has passed since last update.

はじめに

このエントリはQt Advent Calendar 2017の一日目の記事です。
今回は、動的なデータに合わせて折れ線グラフを更新するという想定で、QMLのCanvasで描いた場合とQQuickPaintedItemを継承してQPainterで描いた場合とを比較してみました。
大きな要素としては以下の3つです。

  • なんとなくLive Coding的な仕組み
  • QMLのCanvasで折れ線グラフを描く
  • QQuickPaintedItemを継承して折れ線グラフを描く

コードは全てGitHubにあげてあります

前提

  • データは8系列、各系列300点データ
  • 各系列は0~30の範囲で推移
  • エラー処理などは入っていません
  • マジックナンバー多め

なんとなくLive Coding的な仕組み

QML変更して動作確認、というサイクルを繰り返すことになると思ったので、QMLファイルを更新したら自動で再読み込みする仕組みを先に作っておきました。これはmain.cppに書いてあります。

[1] 指定したルートディレクトリから再帰的に辿って見つかったqmlとjsファイルをQFileSystemWatcherで監視して、変更が見つかったら再読み込みさせています。

Windowsでは変更直後に再読み込みすると失敗することがあったのでSleepを入れています。また2回目以降のfileChangedシグナルが出なかったので毎回addPathしなおしています。
シャドウビルドOFFの前提でQMLのパスを書いてあります。

QMLのCanvasで折れ線グラフを描く

[2] Chart1.qmlのCanvas.onPaintでガリガリと描いています。getContextでContext2Dインスタンスを取得して、strokeStyleとlineWidthで色と線幅を指定し、beginPath, moveTo, lineToでpathを作ってstrokeで描画する流れです。

QQuickPaintedItemを継承して折れ線グラフを描く

[3] QQuickPaintedItemを継承したQPainterChartクラスを作り、paint関数を上書きしてこの中で折れ線グラフを描いています。
[4] main関数でQML側にこのクラスを登録しています。
[5] 登録した型をChart2.qmlで使用しています。

※ 始めはQPainterChartのchartDataプロパティをQList<QList<int>>型にしていてQMLからセットされずに悩んでいました。QMLから受ける時はQVariantListなんですね。

比較

手元の環境(Windows10 + Qt5.9.1MSVC)では、10fpsでQQuickPaintedItemで描くとCPU使用率15%前後、Canvasで描くと9%前後という結果になりました。QPainterで描く方が速いのかと思っていたので意外でした。

AI-medical-service
近未来の内視鏡医療を実現する医療ベンチャー
https://www.ai-ms.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away