Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct
[SOLVED] QML ListView of Images segfaults when an image is not visible
Hello. First of all, please note that I have read http://doc.qt.nokia.com/4.7/qml-listview.html#delegate-prop and know that states should not be stored in delegates. However, I'm still trying to figure out exactly what that means in my case-- it may very well be my problem.
I am trying to prune my code into an example that I can post here. Until then, please allow me to explain my design and issues in words-- you may know immediately what I'm doing wrong.
The general idea of the program is to receive multiple video streams, and display the list of streams represented by a snapshot inside a QML ListView. The ListView is inside a dock inside a main window (via QDeclarativeView), and the central widget of the main window is a QLabel. When one of the snapshots are selected, the snapshot itself begins updating with the video stream, and the video stream is also displayed in the central QLabel.
My problem is with the ListView. The ListView delegates are QML Image elements. The ListView is working with a "SnapshostListModel" class inherited from QAbstractListModel, which have multiple "SnapshotListItems" inherited from QObject. The SnapshotListItem class has an ObjectId role so the QML Image element knows which one it represents. Also, the SnapshotListModel additionally inherits from QDeclarativeImageProvider so it can give images to the QML Image elements (specified by the ObjectId). However, the images that it provides are actually stored in the individual SnapshotListItems. Perhaps that right there is my problem.
So, you load this program up, and it's receiving video streams. Say it receives three, with object IDs 1, 2, and 3. You see three static snapshots in the ListView. You click one. The snapshot you selected is now dynamically updating-- essentially, the video stream is now being shown on both the central QLabel and the QML Image element. The video frames are each scaled appropriately to fit in the QML Image element while maintaining aspect ratio.
The issues come when you begin to scroll around. Scrolling far enough one way or the other (so that you can no longer see the snapshot) occasionally causes a segfault when the SnapshotListItem calls scaled() on its QImage snapshot. Does this have something to do with the delegate being destroyed? The SnapshotListItem's destructor is never called. Also, the one that breaks is never the one that's currently displaying video-- it's always one of the static ones. That might have something to do with me setting the currentIndex when a snapshot is selected.
Another issue is that, if it doesn't segfault, many times when the snapshot comes back into view it is completely distorted.
I know code would help, and I'm working on it. Until then, how screwed up is my design? What would be the best way to fix this?
Thanks for your help.
Perhaps a simpler and related question would be: Do QML delegates being destroyed at any time mean anything for the list items in C++ that they were representing?
Wait... further testing results: Adding a cacheBuffer of, say, 1000 (more than enough for my test cases) to my ListView doesn't help at all. Does that mean that delegate destruction isn't my problem here?
Hmm... this may not have anything to do with QML at all-- I decided to change from QImages to QPixmaps, and now I can't duplicate the behavior. Any ideas for what happened here?