PDA

View Full Version : Qt OpenGL data synchronization / Model/View implementation



HugoCodes
15th November 2015, 11:16
Hello everyone,

I am trying to develop an application with Qt 5.5 and OpenGL. The basic work of the application will be to load simple objects, modify their positions in a scene and save them together with other attributes (material, name, parents/child relations etc...).

The only thing I am struggling about for a week now is that I really don't know how I should take on the problem of synchronizing data. Let's say I have some kind of SceneGraph class which takes care of all SceneObjects. Those SceneGraphs should be rendered in a SceneView-Widget which can be used to modify it's Objects via transformations. Now how would I tell every SceneView that an Object changed it's position? I thought of the Model/View architecture for a moment but I am not really sure how this implementation should look like. What would be the best way to handle Objects like that in different Windows/Widgets but still have one single piece of data?

Thanks in advance and I am sorry I am still in the process of learning gui-development with Qt.

Overview of my general idea for the implementation:

SceneObject:
-Holds the mesh-information (verticies, uvs, etc..)
-Has a name (QString)
-Has a material
-Has a transform storing position, rotation and scaling information
(Important: these datatypes should be synchronized in all views)

SceneGraph:
-Contains different SceneObjects and is passed to SceneViews

SceneView:
-The QWidget responsible for drawing the Scene correctly in any QWindow.
-Has it's own camera to move around.
-Handles UserInput and allows transformation of SceneObjects.

d_stranz
16th November 2015, 16:08
You could derive a class from QAbstractItemModel to do this. When the data for an item changes, your model would emit the dataChanged() signal. Your "view" would connect to this signal and update whatever properties had changed for the object. Typically, your Qt model will contain a pointer or other reference to your real model - the scene graph - and you will implement methods on your Qt model that the scene graph can use to tell the Qt model when to update. The Qt model in this case is simply a piece of architecture that adapts your scene graph to views of it that allows you to take advantage of the Qt model-view system.

If you derive your view from QAbstractItemView, you can simply reimplement the dataChanged() slot. The Qt machinery behind the model-view architecture will make the right connections for you when you set the model on the view, so all you will need to do is to respond appropriately when the slot is invoked.

Deriving may not be possible if you are using a Qt-based OpenGL view, since you can't multiply inherit QObject-based classes. In this case, you can create add the appropriate slots yourself, and add a setModel() method that will connect model signals to these slots.

Depending on the complexity of the interactions between your model and the view, trying to wrap it in the Qt Model-View architecture might be just too much overhead. It might be easier and cleaner to devise a simple set of signals and slots that your scene graph (or the objects in it) and views can use to communicate state changes.

HugoCodes
16th November 2015, 18:55
Thank you for answering!

Okay so I think I will take the custom approach and just stick to plain signal - slot connections between View and SceneGraph.

d_stranz
16th November 2015, 21:22
Depending on how decoupled you want things to be, you can either implement a setSceneGraph() (or similar) method on the view class and have the view connect up to the scene graph's signals in there, or you can make the connections in your main window class when you create the views. In the first case, the views need to know about the scene graph's signals. In the second case, only the main window needs to know about the signals and slots. This might be appropriate if you don't want the scene graph and the views to know too much about each other so your implementation can remain flexible as it evolves.