0

I have a pyqt5 app with an MVC structure similar to the one described here. When the model is edited, a pyqtSignal is emitted, after which the controller will update the view (and, of course, the other way around). To enable the use of pyqtSignals, the model class inherits from the QtCore.QObject class.

I now want to duplicate the current "window" - creating a copy of the model, and coupling it to a newly created view and controller. However, the fact that the model inherits from QtCore.QObject makes it so I cannot copy it (TypeError: cannot pickle 'Model' object - QObjects cannot be copied by design).

What would be the best way to approach this problem?

ekhumoro
  • 115,249
  • 20
  • 229
  • 336
Wouter
  • 41
  • 1
  • 5
  • The example given in your link is a very poor one since it does not use any of Qt's view/model classes. If you want to understand how to implement this properly, please read [Model/View Programming](https://doc.qt.io/qt-5/model-view-programming.html) in the Qt docs. One of the main points of separating the model from the view, is that it allows a single model to be used with multiple views. It makes little sense to think about *copying* a model. – ekhumoro Jul 22 '22 at 13:18
  • I use more of a application-level MVC-structure, which differs somewhat from the MV-methods described in the QT-manual (like [this](https://stackoverflow.com/questions/26698628/mvc-design-with-qt-designer-and-pyqt-pyside)). My application is basically a matplotlib plotter. I want to open a new window that uses the same plotting data (PlotDataModel) but should enable the user to select different ranges, filters and plot colors (PlotSettingsModel). Though Initialially, I want the new window to have the same plot-settings, for which I need to copy the PlotSettingsModel. – Wouter Jul 22 '22 at 16:18
  • That all sounds very specific to matplotlib, which you don't mention at all in your question. It's [debatable](https://stackoverflow.com/q/5543198/984421) whether there's any agreed upon definition of what MVC "really" means - but whatever. There's no generic shortcut to cloning such objects. If matplotlib doesn't give you any help, you'll have to write your own "copy-constructor" that duplicates all the relevant properties in a new instance. It's entirely up to you to decide what gets duplicated and in what way. – ekhumoro Jul 22 '22 at 17:15
  • The PlotSettingsModel in this case is just a custom class which contains the user-specified plotsettings (e.g. int/float/datetimes for plotting ranges and that sort of things). Thanks for your input, I thought maybe there were more generic ways to do such a copy operation but I think I'll take your advice. – Wouter Jul 22 '22 at 17:40
  • Can't you just use composition instead of inheritance? A class doesn't have to ***be*** a QObject in order to make use of signals and slots. – ekhumoro Jul 22 '22 at 17:52
  • I'm using properties/setters to emit attribute changes from the model so that is probably difficult to achieve in a nice way in my case. – Wouter Jul 22 '22 at 19:25

1 Answers1

0

Based on @ekhumoro suggestion, I ended up creating a separate data-class. The 'model'-class has an instance of this data-class and makes it so I can easily create copies.

In most cases it might be easier to try to migrate all model-changed-signals to the controller instead, though.

Wouter
  • 41
  • 1
  • 5