简体   繁体   中英

Updating QML from highly dynamic C++ data model: Timer vs Property binding

Assume a C++ business model which is potentially changing its underlying data very quickly (let's say up to 1000 Hz). In my specific case, this would be a wrapper around a network data callback mechanism (a ROS-subscriber to be more precise) running in its own thread. Think of the data as some sensor reading. Further assume that we are dealing with simple data, eg a single double value or a string in the worst case.

What would be the best way to visualize such data in a QML component? Best here is with respect to being gentle with resources, minimizing the delay between model state and view, and being as clean code as possible?

I came up with the following options:

  1. Bind the data as property of the model to the view, and emit a dataChanged() signal on every update of the data:

    • Pro: Elegant code, lowest resource usage in case of low data update rates.
    • Con: High signal frequency will spam the GUI and maximize resource utilization, potentially rendering the system unresponsive.
  2. Use a QML-Timer and poll the model at a specific interval (eg 10 - 60 Hz):

    • Pro: Upper limit on resource utilization, steady rate
    • Con: Timer itself consumes resources; not as elegant as data binding; if data generation/callback rate is lower than timer rate, unnecessary polling calls have to be made.
  3. Use data binding as in 1. but throttle the signal emitting frequency inside the C++ model using a QTimer (or another timer like boost's), ie, only emit the dataChanged() signal at specific intervals:

    • Pro: Same as 2.
    • Con: Same as 2.
  4. Combine Timer from 3. with some kind of check whether the data actually changed, prior to emitting the signal, thus avoiding unnecessary signal emitting if data has not changed:

    • Pro: Same as 3.
    • Con: same as 3. but even less elegant; increased risk to induce a bug because logic is more complicated; model is harder to reuse as the data changed check highly depends on the nature of the data

Did I miss an option (besides not producing so much data in the first place)? What would be your choice or the most QT/QML way of realizing this?

First of all, have you established that there is a performance problem?

I mean granted, 1000 updates per second is plenty, but is this likely to force GUI updates a 1000 times a second? Or maybe the GUI only updates when a new frame is rendered? Any remotely sane GUI framework would to exactly that. Even if your data changes a gazzilion times per second, GUI changes will only be reflected at the frame rate the GUI is being rendered in.

That being said, you could work to reduce the strain on the backend. A typical "convenience" implementation would burden the system, and even if any contemporary platform that Qt supports could handle 1000 Hz for an object or two, if those are many, then you should work to reduce that. And even if not directly detrimental to system performance, efficiency is always nice as long as it doesn't come at a too high cost development wise.

I would not suggest to directly update data using a property or model interface, as that would flood with signal notifications. You should handle the underlying data updates silently on the low level, and only periodically inform the property or model interface of the changes.

If your update is continuous, just set a timer, 30 Hz or even less outta be OK if a human is looking at it.

If it is not, you could use a "dirty" flag. When data changes, set the flag and start the update timer as a single shot, when the timer triggers and notifies the update, it clears the flag and suspends. This way you avoid running the timer without any updates being necessary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM