Solved set only the value of a dialog gadget

hi there,

i have a fairly complex command plugin with lots of gadgets, mostly sliders. i initiate them with:

self.AddEditSlider(id=10005, flags=c4d.BFH_SCALEFIT, initw=0, inith=0)
self.SetFloat(id=10005, format=c4d.FORMAT_METER, min=0 max=10, step=.1, value=1 )

later, at some other points in the code i want to change the value. since i have lots of different settings for min, max, step and format, i'd like to only set the value. but doing it like this:

self.SetFloat(id=10005, value=5)

will reset min, max, step and format to their defaults.
An object plugin would have the function SetParameter(), but not the command plugin.

is there any way to do this?


Hi @datamilch sadly, there is nothing built-in for your use case, if you have the same value for the format/min/max/step the best way would be to override SetFloat, and call the SetFloat from GeDialog with this value. If you have multiple possible values, you will need then to store this data somewhere, find an example bellow.

import c4d

class MyDialog(c4d.gui.GeDialog):

    def __init__(self):
        self.cachedData = {} #Key = GadgetId, Value = list[format, min, max, step]
        self.cachedData["10005"] = [c4d.FORMAT_METER, 0, 10, 0.1]
        self.cachedData["10006"] = [c4d.FORMAT_METER, 1, 3, 0.5]

    def CreateLayout(self):
        self.AddEditSlider(id=10005, flags=c4d.BFH_SCALEFIT, initw=0, inith=0)
        self.AddEditSlider(id=10006, flags=c4d.BFH_SCALEFIT, initw=0, inith=0)
        self.SetFloat(10005, 1)
        self.SetFloat(10006, 2)
        return True
    def SetFloat(self, gadgetId, value, floatFormat=c4d.FORMAT_METER, minValue=0, maxValue=10, step=0.1):
        # Check if we have some cached data, if not then use what was passed as argument. 
        # The other way can also be done here it's just an example
        if str(gadgetId) in self.cachedData:
            floatFormat = self.cachedData[str(gadgetId)][0]
            minValue = self.cachedData[str(gadgetId)][1]
            maxValue = self.cachedData[str(gadgetId)][2]
            step = self.cachedData[str(gadgetId)][3]
        return super(MyDialog, self).SetFloat(id=gadgetId, format=floatFormat, min=minValue, max=maxValue, step=step, value=value)

# Main function
def main():
    diag = MyDialog()
    diag.Open(dlgtype=c4d.DLG_TYPE_MODAL_RESIZEABLE, defaultw=960, defaulth=600)

# Execute main()
if __name__ == '__main__':


oook, that escalated quickly - in a nice way though.
i was thinking of a way to store my default values anyway, so this perfect. i think.

i'll have to read about 'super()' ... is this just good practice in this case or actually needed?
could i just return self.SetFloat(...) ?

Hi by default when you call self.X it will call the method in the current class, if you don't have this method, then python will search if this method exist in the parent class, and so on until it find it (if you want to know more search python mro (Method Order Resolution) on google).

So in this particular case since there is a SetFloat defined method in the class that inherit from GeDialog, by default it will call this SetFloat method and not the one from GeDialog (which is actually talking to c4d to change the UI), so in this case you need to call super.. so tell python to not call the SetFloat from the class I inherit but from the parent class (so GeDialog).

If there is still some point unclear, feel free to ask.

ah got it, thanks for the quick explanation!
so without super i would call SetFloat in an endless loop, because it returns itself.

huge thanks again @m_adam!

the trick with storing the data in a dictionary was super helpful.
now i can jump between documents and the dialog updates properly. :flushed: