Solved Python: Key Error while initializing GUI, Dictionary, self

"Dictionary" "self" and old SDK sample code might be my issue, but can somebody help me and point out, why I get a key error by just adding more gui elements to this old SDK ToolData plugin liquid-painter sample code.

adding a Checkbox (Bool) worked, but adding other gui elements breaks the smaple code somehow.

Key error on line 39 & 107 (marked in the Code so you don't need to search)
Thanks in advance
R20 Visualice

import c4d
import os
from c4d import gui, plugins, bitmaps

# be sure to use a unique ID obtained from www.plugincafe.com
PLUGIN_ID = 1015073

# for GeLoadString values must match with the header file
IDS_PRIMITIVETOOL = 50000

class SettingsDialog(gui.SubDialog):
    parameters = None

    def __init__(self, arg):
        self.parameters = arg

    def CreateLayout(self):
        self.GroupBegin(id=1000, flags=c4d.BFH_SCALEFIT, cols=2, rows=5)
        self.GroupBorderSpace(1, 1, 1, 1)

        # Bool
        self.element = self.AddStaticText(id=2003, flags=c4d.BFH_SCALEFIT, initw=1, name="Extend Vector: ", borderstyle=c4d.BORDER_NONE)
        self.element = self.AddCheckbox(id=2002, flags=c4d.BFH_SCALEFIT, initw=1, inith=0, name="")
        #valuebool = self.parameters['extend_vector']
        self.SetBool(2002, False)

        # Extension Value
        self.element = self.AddStaticText(id=3001, flags=c4d.BFH_SCALEFIT, initw=1, name="Extension Ratio: ", borderstyle=c4d.BORDER_NONE)
        valueextension = self.parameters['extension_ratio']
        self.AddEditSlider(id=3002, flags=c4d.BFH_SCALEFIT)
        self.SetFloat(id=3002, value=valueextension, min=0.1, max=100, step=0.1, min2=0.0001, max2=1000, quadscale=True)

        print self.parameters

        self.element = self.AddStaticText(id=1001, flags=c4d.BFH_SCALEFIT, initw=1, name="Sphere Size: ", borderstyle=c4d.BORDER_NONE)
        valuespheresize = self.parameters["sphere_size"]                         
# first key error 
        self.AddEditNumberArrows(id=1002, flags=c4d.BFH_SCALEFIT)
        self.SetFloat(id=1002, value=valuespheresize, min=0, max=20)

        self.GroupEnd()
        return True

    def Command(self, id, msg):
        if id == 1002:
            self.parameters['sphere_size'] = self.GetFloat(1002)
            print "Sphere Size: ", self.GetFloat(1002)
        if id == 2002:
            self.parameters['extend_vector'] = self.GetBool(2002)
            print "Extend Vector:", self.GetBool(2002)
        if id == 3002:
            self.parameters['extension_ratio'] = self.GetFloat(3002)
            print "Extension Ratio: ", self.GetFloat(3002)
        return True


class AVTTool(plugins.ToolData):
    # Inherit from ToolData to create your own tool

    def __init__(self):
        self.data = {'sphere_size': 15}
        self.data = {'extension_ratio': 1}

    def GetState(self, doc):
        if doc.GetMode() == c4d.Mpaint: return False
        return c4d.CMD_ENABLED

    def Debug(self, msg):
        # c4d.CallCommand(13957) # Konsole loeschen
        print "Konsole geloescht."
        return True

    def KeyboardInput(self, doc, data, bd, win, msg):
        key = msg.GetLong( c4d.BFM_INPUT_CHANNEL )
        cstr = msg.GetString( c4d.BFM_INPUT_ASC )
        if key == c4d.KEY_ESC:
            # do what you want
            print "ESC Key Pressed."
            # return True to signal that the key is processed
            return True
        return False

    def MouseInput(self, doc, data, bd, win, msg):
        mx = msg[c4d.BFM_INPUT_X]
        my = msg[c4d.BFM_INPUT_Y]

        device = 0
        if msg[c4d.BFM_INPUT_CHANNEL] == c4d.BFM_INPUT_MOUSELEFT:
            device = c4d.KEY_MLEFT
        elif msg[c4d.BFM_INPUT_CHANNEL] == c4d.BFM_INPUT_MOUSERIGHT:
            device = c4d.KEY_MRIGHT
        else:
            return True

        null = c4d.BaseObject( c4d.Ometaball )
        null[c4d.METABALLOBJECT_SUBEDITOR] = 10
        null.MakeTag( c4d.Tphong )

        doc.AddUndo( c4d.UNDO_NEW, null )

        doc.InsertObject( null )
        doc.SetActiveObject( null )
        c4d.DrawViews( c4d.DA_ONLY_ACTIVE_VIEW | c4d.DA_NO_THREAD | c4d.DA_NO_ANIMATION )

        rad = self.data['sphere_size']                                                 
# second key error 
        dx = 0.0
        dy = 0.0

        win.MouseDragStart( button=device, mx=int( mx ), my=int( my ),
                            flags=c4d.MOUSEDRAGFLAGS_DONTHIDEMOUSE | c4d.MOUSEDRAGFLAGS_NOMOVE )
        result, dx, dy, channel = win.MouseDrag()
        while result == c4d.MOUSEDRAGRESULT_CONTINUE:
            mx += dx
            my += dy

            # continue if user doesnt move the mouse anymore
            if dx == 0.0 and dy == 0.0:
                result, dx, dy, channel = win.MouseDrag()
                continue

            cl = c4d.BaseObject( c4d.Osphere )

            cl.SetAbsPos( bd.SW( c4d.Vector( mx, my, 500.0 ) ) )
            cl[c4d.PRIM_SPHERE_RAD] = rad
            cl.InsertUnder( null )

            c4d.DrawViews( c4d.DA_ONLY_ACTIVE_VIEW | c4d.DA_NO_THREAD | c4d.DA_NO_ANIMATION )
            result, dx, dy, channel = win.MouseDrag()

        if win.MouseDragEnd() == c4d.MOUSEDRAGRESULT_ESCAPE:
            doc.DoUndo( True )

        c4d.EventAdd()
        return True

    def GetCursorInfo(self, doc, data, bd, x, y, bc):
        if bc.GetId() == c4d.BFM_CURSORINFO_REMOVE:
            return True

        bc.SetString( c4d.RESULT_BUBBLEHELP, plugins.GeLoadString( IDS_PRIMITIVETOOL ) )
        bc.SetLong( c4d.RESULT_CURSOR, c4d.MOUSE_POINT_HAND )
        return True

    def AllocSubDialog(self, bc):
        return SettingsDialog( self.data )  # always return new instance


if __name__ == "__main__":
    bmp = bitmaps.BaseBitmap()
    dir, file = os.path.split(__file__)
    fn = os.path.join(dir, "res", "AligntoVector.tif")
    bmp.InitWith(fn)
    plugins.RegisterToolPlugin( id=PLUGIN_ID, str="Py-AlignToVector",
                                info=0, icon=bmp,
                                help="Select two Points to generate a Vector. Then Click additional points to move them onto the Vector.",
                                dat=AVTTool() )

Hello,

as always, please use the Q&A system and also tell us the version of Cinema 4D you are using.

There is no issue with adding GUI elements. The issue is with these lines of code:

self.data = {'sphere_size': 15}
self.data = {'extension_ratio': 1}

Please make sure you understand how to use a Dictionary in Python.

best wishes,
Sebastian

Thanks Sebastian,

I did read your dictionary link but was wondering why then this code works in the sample sdk

what i've tried so far to set or read the dic. in the init

        self.data["sphere_size"] = 15
        self.data["extension_ratio"] = 1

        self.data.get("sphere_size")
        self.data.get("extension_ratio")

        self.data = parameters["sphere_size"] = 15
        self.data = parameters["extension_ratio"] = 1

        self.data = parameters.get("sphere_size")
        self.data = parameters.get("extension_ratio")
        
        self.data = {'sphere_size': 15}       # original SDK Code !
        self.data = {'extension_ratio': 1}

This is obviously a problem of myself understanding the concept of "self" but I really like to learn by solving c4d problems instead of generic Phyton lessons.

kind regards mogh
R20 Visualize

Hello,

this isn't a Cinema 4D issue; it has also nothing to do with "self". It is just about understanding basic Python syntax.

Just run this code

someDict = { "a", 1}
someDict = { "b", 2}
print(someDict)

to see that it only contains one key/value pair. This is because the second line does not add a key/pair value. The assignment operator overwrites the variable with a new Dictionary.

I strongly recommend do to some generic Python lessons.

best wishes,
Sebastian

thanks solved:

self.data = {'sphere_size': 15, 'extension_ratio': 1, 'extend_vector': False}

kind regards