Update JavaFX Live nodes outside Application Thread - javafx

The JavaFX Application Thread. Sources I can find says all updates on nodes must happen in this thread.
I am trying to find the documentation for this and if there are any exceptions to this rule.
https://docs.oracle.com/javase/8/javafx/interoperability-tutorial/concurrency.htm
As it says:
The JavaFX scene graph, which represents the graphical user interface of a JavaFX application, is not thread-safe and can only be accessed and modified from the UI thread also known as the JavaFX Application thread.
https://docs.oracle.com/javase/8/javafx/get-started-tutorial/jfx-architecture.htm#A1107438
Any ”live” scene, which is a scene that is part of a window, must be accessed from this thread. A scene graph can be created and manipulated in a background thread, but when its root node is attached to any live object in the scene, that scene graph must be accessed from the JavaFX application thread.
I have experienced that not all updates on a node must be done on the JavaFX AT. Some calls to update the node works fine outside this thread.
For instance updating Text textProperty does not require running within the JavaFX AT. Nor thus it looks like setting tooltip does either, or changing visibility/disable/managed.
Updates on Label textProperty outside of the JavaFX AT will throw an
IllegalStateException: Not on FX application thread; currentThread = Task

You are confusing what is not allowed with what throws exceptions. Just because something doesn't throw an exception doesn't mean it is allowed, or that it is safe, or that it is guaranteed to work.
All changes to nodes that are part of a live scene graph must happen on the JavaFX Application Thread.
JavaFX makes a best effort to throw exceptions if this rule is violated. Checking the thread costs time, and for some operations the performance cost of checking the thread is too high, so not all violations of the rule will result in an exception. However, violating the rule is prone to inconsistent behavior at arbitrary times in the future, even if no exception is thrown. See Moving circle randomly disappears (javafx) for an example of this happening in practice.

Related

Is it possible to re-paint/update content in a Qt GUI application although the main thread is blocked?

There is a lot of discussion (e.g. here) going on about spinning or moving busy indicators in a GUI but I could not find a single one that clearly states that it is impossible to re-paint/update any content in a GUI application while the main thread is blocked.
This question is actually a general one and is not necessarily directly related to Qt GUI applications.
When the main thread of a GUI is performing a blocking operation no events are processed and no content can be re-painted. There are two "recommended" approaches:
Using worker threads
Splitting the work in chunks and updating the UI "just not that often"
The problem is that there are operations that simply cannot be moved to worker threads or any other asynchronous mechanism. The best example is the serialization and de-serialization of the UI itself. In both scenarios the user must not click happily in the UI and change settings while the settings, properties, etc. are taken from the widgets (during the saving) or applied to the widgets (during the loading). This is true for the threading approach as well as the splitting into chunks.
Edit: Another example is the application of stylesheets to a complete GUI. Imagine that a user wants so select a "dark" scheme. All of the widgets need to be updated and the currently visible ones needs to be re-painted. During this step the event loop cannot run. A similar discussion can be found here.
In my case I'm working on an embedded device so there is another approach:
Directly overwriting a specific region of the framebuffer
This approach feels very ugly and comes with a lot of problematic scenarios and surly involves lots of debugging.
The last but sad approach:
Do not use any moving/updating content at all and just show something static such as "...in progress..."
Well, this is just sad...
Do you agree on these observations? Does anyone know of a different approach or concept in general un-related to Qt?
The problem is that there are operations that simply cannot be moved to worker threads or any other asynchronous mechanism.
I can't agree. These operations should be split into blocking and non-blocking operations. Everything that blocks should be handled asynchronously, or, if no non-blocking APIs are available, handed off to a worker thread.
The best example is the serialization and de-serialization of the UI itself.
I find it a particularly poor example mainly because I've yet to run into a need for blocking the GUI, and serialization doesn't call for it.
In both scenarios the user must not click happily in the UI and change settings while the settings, properties, etc. are saved or loaded.
Construction and destruction of the widgets should be very quick, if that's what you mean by "deserializing" the UI. Recall that the blocking I/O and long parsing has been done in another thread. Almost all Qt widgets certainly are quick to set up, and those that are not are a necessary evil that you have no choice but to live with. If you have your own widgets that do blocking operations like disk or registry access in their constructors or event handlers (plenty of such "code" exists), fix them.
If you're merely talking about setting widget values, this again is super-quick and can be done all in one batch. You will probably need a viewmodel to asynchronously interface between the view (widgets, QML view, or a QAbstractItemView) and the data source.
Disk I/O and parsing/output of the on-disk representation belongs in a separate worker. Once you create an internal representation, it can be passed to the gui thread to build the widget tree or populate the interface.
You should implement thread-safe models using QAbstractItemModel or a similar interface, and populate them in a worker thread, and let the GUI thread react to the updates in real time.
If you wish to indicate to the user that a part of the interface is not usable yet, e.g. while a model gets populated, you could do so via an overlay, making sure that you temporarily disable the focus on the widgets that are under the overlay. This is not hard and I'd find it amusing if your entire question could be reduced to "how do I make a part of the UI inaccessible while it's being modified".
The key thing missing is that the UI should handle asynchronously reacting to a model changing its state. For all I care, it could take an hour to load the data needed to fully populate the model. It doesn't mean that your application should be unresponsive. Simply make the parts of the UI that can't be interacted with inaccessible for interaction. Ensure that other parts of the application that need the configuration data are similarly either inaccessible or in a partially usable state that will asynchronously revert to full state once the configuration becomes available.

QOpenGLWidget stops repainting on update()

I have a custom QDialog which contains a hierarchy with 4 separate instances of QOpenGLWidget.
Each of these QOpenGLWidget's has its own GL context, and renders a different scene.
I have a loop which calls update() (the recommended method for repainting them) on each QOpenGLWidget regularly (the focused one more regularly, however I think this is irrelevant to the problem).
My problem is that eventually after random amounts of time (sometime it happens quickly, other times it won't happen for 10+ mins), one or more QOpenGLWidget's will stop repainting when update() is called.
I have however noticed that resizing the stalled QOpenGLWidget causes a single repaint event to be triggered.
I can see with the debugger that update() is being called on all the QOpenGLWidget's, but this is never triggering paintGL() (the repaint method) for the stalled widgets. and that updatesEnabled() always returns true, regardless of wether update() is triggering repaints or not. QT also isn't printing any errors or warnings to console.
The dialog containing these widgets is running in a separate thread to the one that triggers update(), so I can't call repaint() directly (without writing my own event loop).
Adding QApplication::sync() to the method that triggers update() doesn't make a difference either.
I'm inclined to think it occurs more when there's less ram available, however less ram is in the order of 800mb, and the application uses significantly less than that. So my gut is probably wrong.
I'm not a big user of QT, so I'm not too sure where to go from here debugging the issue further, any suggestions would be welcome. Given the reproducibility of the error involves waiting an unknown length of time and a more complex and multi-threaded project, can't imagine there would be much benefit to me attempting to reproduce the bug with a small snippet of code.
Update:
Just ran into exactly the same issue when calling update() on a QGraphicsScene, however it was occurring after only a couple of updates every time.
Found this suggestion to instead update the viewport with viewport()->update() and it appears to have fixed the problem.
QOpenGLWidget however doesn't have a viewport to update in the same way.

Update QGraphicsScene from another, non-main thread

I'm pretty new to QT's graphic view frame, and I couldn't find anything about this in the docs or on Google.
I have a GUI application that draws a representation for some data. The application itself does some work with matrices / vectors (a neural net thing) and has to represent it on a QGraphicsScene. So far so good, but I've noticed that the app segfaults & crashes sooner or later (and usually sooner) if I try to update the QGraphicsScene from another thread. The QT Docs say nothing about thread-safety & Google gives nothing. What I want (and pretty much need) to do is run the calculations & update the GUI representation accordingly, but the GUI controls etc themself have to remain responsive. As I said, my first thought was to do the whole thing in another thread, but it crashes randomly if I try to.
Is there any "accepted practice" to do this kind of thing in QT or is there some gotcha that I don't know of in the graphics view framework itself?
The Qt docs actually say quite a lot about thread safety. If the docs for QGraphicsScene don't say anything it's because they are not thread-safe, consistent with the behaviour you are seeing.
What you need to do is run your calculations in another thread and synchronise that thread with the main GUI thread as appropriate. A simple way to do this would be to set a flag in the main thread when the calculations are ready for display. That way you can call the appropriate QGraphicsScene methods in the main thread at the right time by simply checking the flag.

QGraphicsScene::clear() method crashes only in release mode

I inherited my scene from QGraphicsScene. I add many items(QGraphicslineItem, QGraphicsItem, QGraphicsTextItem) on this scene. Whenever i try QGraphicsSceneClear method it crashes on release mode. It works fine on debug mode.
Note: Some items have child items and/or have pointers to other items, so when i delete them i handle them in the destructor (deleting pointers to other items etc). i guess pointers to other items makes it crashing but i do not understand why it crashes only on release mode.
The call stack in release mode is not useful, but it does say access violation on the console.
Your problem is some of your items are deleting other items in the same scene. You have no control (well, not directly) on the order of removal of items when calling clear(). Say you have items A, B, and C. C maintains a pointer to both A and B. When clear() is called, A and B may have already been removed and deleted when C's destructor is called.
As for the crash only happening in release mode, the order of removal may depend on the level of compiler optimization. This is really common when dealing with dangling pointer.

How to spot memory leaks in profiler?

I have an AIR/Flex app I made, I have a few people testing it and everyone is reporting that after leaving it running for a while, it is making all there machines run very slow. It runs fine at first so this must be a memory leak somewhere. I used the profiler on this and the only thing that shows as using a substantial amount of memory is MethodQueueElement which is not a class I wrote, and I have no idea what it does, I am assuming its part of the Flex framework. I am not familiar with using a profiler so I am not sure what all I shuld be looking at, that was the only class that was high on "memory" and it said it had over 100,000 instances. If this is my problem what can I do to fix it? I do not even know what this class does or anything about how it gets instantiated.
Thanks
The MethodQueueElement class is an internal class of the mx.core.UIComponent class.
It is used to represent on method call that has been enqueued by a callLater call.
The callLater method is part of the public interface of UIComponent, so either you call it in your code, or it is beeing called by the framework (as it happens in UIComponent.setFocus e.g.)
To free all MethodQueueElement instances, UIComponent replaces the current array of MethodQueueElements by a new (empty) one. (in the callLaterDispatcher2 method) So the only way to make a memory leak out of it is, to prevent callLaterDispatcher2 from beeing called.
To debug this, you can start to set breakpoints (while you app is running) in the methods callLater (here your instances get created, so somehow it gets called all the time, look at the stacktrace here!), callLaterDispatcher2 (i suppose it wont get called), and check whether UIComponentGlobals.callLaterSuspendCount is != 0, which could be the reason callLaterDispatcher2 doesn't get called.
Should the latter be the case, i suspect, that you have tweens or something else calling UIComponent.suspendBackgroundProcessing but then not calling resumeBackgroundProcessing (because of an exception terminating the code before reaching the resumeBackgroundProcessing call e.g.)

Resources