taurus-org / taurus

Moved to https://gitlab.com/taurus-org/taurus
http://taurus-scada.org
43 stars 46 forks source link

CustomWidgetMap is overridden by TaurusGui #943

Open stanislaw55 opened 5 years ago

stanislaw55 commented 5 years ago

Hi, I have a TaurusGUI for Sardana with my own custom widgets for motors and detectors in Sardana. I've created dictionary with custom widgets for displaying my custom widgets in TaurusForm. However, I'm not sure what is the correct way to inject my dictionary with custom widgets. For now I'm calling setCustomWidgetMap in my TaurusForm in constructor and as standalone widget this works just fine. Things are different in case on embedding this TaurusForm in TaurusGui as a panel.

customWidgetMap is overriden by TaurusGui using taurus.tauruscustomsettings.T_FORM_CUSTOM_WIDGET_MAP. Looking at source code, it is obviously done when loading configuration and creating custom panel. TaurusGui loads taurus.tauruscustomsettings.T_FORM_CUSTOM_WIDGET_MAP as its customWidgetMap (falling back to empty dict). Then, when creating panel via loadConfiguration or createCustomPanel, widget's setCustomWidgetMap method is called with TaurusGui's customWidgetMap as argument. This causes override of map. The question is: Is this intended behaviour?

I expected from TaurusGui to keep customWidgetMap set in widget constructor. However, this may not be the best place to do it. If so, where should I set this map? It's clear that in current situation it must be set after loading configuration.

On the other hand, I would think that current behaviour of overriding is not best one. From my point of view, setting this map should look like this:

# in TaurusGui class
if hasattr(w, "setCustomWidgetMap") and hasattr(w, "getCustomWidgetMap"):
    tmp = self.getCustomWidgetMap().update(w.getCustomWidgetMap())
    w.setCustomWidgetMap(tmp)

In that case, TaurusGui still has taurus.tauruscustomsettings.T_FORM_CUSTOM_WIDGET_MAP as default widget map. But custom widget map of specific widget is preserved and has higher priority than TaurusGui's.

cpascual commented 5 years ago

First of all, sorry for the mess... all this customwidgetmap stuff comes from an early hack that ended up as API (any suggestions to improve/replace it are welcome).

Now, your proposal of updating the map with the one already in the widget, looks good to me. If you are interested in submitting a PR, it would be welcome.

Alternatively (or as a workaround) you could just change (at run time) the value of taurus.tauruscustomsettings.T_FORM_CUSTOM_WIDGET_MAP. Of course this would affect all taurusforms in the same application, but I guess that is acceptable in many cases.

stanislaw55 commented 5 years ago

First of all, sorry for the mess... all this customwidgetmap stuff comes from an early hack that ended up as API (any suggestions to improve/replace it are welcome).

From my point of view, this is useful and interesting feature. However, one can set customWidgetMap in TaurusForm and in TaurusValue (in constructor) which is a little bit confusing

Alternatively (or as a workaround) you could just change (at run time) the value of taurus.tauruscustomsettings.T_FORM_CUSTOM_WIDGET_MAP.

This is exactly what I actually do to overcome this issue.

If you are interested in submitting a PR, it would be welcome.

Will do (but dunno when)

stanislaw55 commented 4 years ago

Hi @cpascual I have a question regarding custom widget map. Now there's need in my application to have different widgets representing the same types.

For example: there's TaurusForm A with custom widget map AA which is used only for custom view of Sardana motor. In different place, there's need fro TaurusForm B with custom widget map BB which allows to move the same motors (so it can be standard CUSTOM_WIDGET_MAP).

The question is: how to achieve this goal with current behaviour? Is this even possible? Personally I could not come up with any idea

cmft commented 4 years ago

Hola @stanislaw55, @cpascual is on holidays. If your GUI is programmatic you can change the map for the second form using setCustomWidgetMap with the dict(type=class). If it is not, you have to use a custom TaurusForm in your GUI and use a different map for it.

Hope this help you.

stanislaw55 commented 4 years ago

Hi @cmft Thank you for information. My GUI is not programatic so I'll try to create new custom TaurusForm. Thank you for help!

cpascual commented 4 years ago

Hi @stanislaw55 , I am back... I agree with @cmft in that with the current implementation, using a custom form is the best solution