OOP class struggles: treeview envoce gui refresh outside class ListView()



  • Dear Developpers,

    the last days have been enlightening for me because I am getting more comfortable with this class thing ;-) Nevertheless beginner ??? are bound to happen ...

    I have running plugin with a c4d.gui.TreeViewFunctions
    in there def Select from which I would like to triger a GUI refresh inside the class TestDialog(c4d.gui.GeDialog): and therefore outside the class ListView(c4d.gui.TreeViewFunctions):

    The manual calculation of the sum with self._CalcSum() works (by pressing a button) but I would like to have it interactive when the user selects something in the treeview.

    I do not expext you to go through all my code a nice easy example would do I guess.

    2021-02-07-Window_000014.png

    All the code should work besides some not usefull bookmarks ;-)

    import c4d, os
    from c4d import gui
    
    # Be sure to use a unique ID obtained from http://www.plugincafe.com/.
    PLUGIN_ID = 1000011 # TEST ID ONLY
    PLUGIN_NAME = "Cad File Importer"
    #TreeView Column IDs.
    ID_CHECKBOX = 1
    ID_NAME = 2
    ID_OTHER = 3
    
    ID_BOOKMARKLIST = ("C:\\Users\\admin\\Pictures", "E:\Bilder\Bilder Temp\Screenshots", "", "C:\\wrong path", "C:\\")
    
    ID_FOLDERSELECTION_SYSTEM = 1111
    ID_SCANCONTENT = 1112
    ID_PATHSTRING = 1113
    ID_INFOBOX = 201
    ID_CLOSE = 1114
    ID_SELECTALL = 1115
    ID_SUMBOX = 1116
    ID_COLOREDBORDER = 1117
    ID_IMPORT = 1118
    
    class TextureObject(object):
        """
        Class which represent a texture, aka an Item in our list
        """
        texturePath = "TexPath"
        otherData = "OtherData "
        _selected = False
        #filesize = 0
    
        def __init__(self, texturePath, otherData):
            self.texturePath = texturePath
            self.otherData = otherData
            #self.otherData = round(float(otherData) / 1024.0 / 1024.0, 1)
            #self.filesize = filesize
    
        @property
        def IsSelected(self):
            return self._selected
    
        def Select(self):
            self._selected = True
    
        def Deselect(self):
            self._selected = False
    
        def __repr__(self):
            return str(self)
    
        def __str__(self):
            return self.texturePath
            
        def NiceFileSize(self):
            return round(float(self.otherData) / 1024.0 / 1024.0, 1)
        
        
    class ListView(c4d.gui.TreeViewFunctions):
    
        def __init__(self):
            self.listOfTexture = list() # Store all objects we need to display in this list
        
        """
        def _CalcSum(self):
            sumselected = 0
            
            for fileitem in self.listOfTexture:
                if fileitem.IsSelected == True:
                    sumselected += fileitem.otherData
            
            print (round(float(sumselected) / 1024.0 / 1024.0, 1))
            return (round(float(sumselected) / 1024.0 / 1024.0, 1))
        """
        
        def IsResizeColAllowed(self, root, userdata, lColID):
            return True
    
        def IsTristate(self, root, userdata):
            return False
    
        def GetColumnWidth(self, root, userdata, obj, col, area):
            return 80  # All have the same initial width
    
        def IsMoveColAllowed(self, root, userdata, lColID):
            # The user is allowed to move all columns.
            # TREEVIEW_MOVE_COLUMN must be set in the container of AddCustomGui.
            return True
    
        def GetFirst(self, root, userdata):
            """
            Return the first element in the hierarchy, or None if there is no element.
            """
            rValue = None if not self.listOfTexture else self.listOfTexture[0]
            return rValue
    
        def GetDown(self, root, userdata, obj):
            """
            Return a child of a node, since we only want a list, we return None everytime
            """
            return None
    
        def GetNext(self, root, userdata, obj):
            """
            Returns the next Object to display after arg:'obj'
            """
            rValue = None
            currentObjIndex = self.listOfTexture.index(obj)
            nextIndex = currentObjIndex + 1
            if nextIndex < len(self.listOfTexture):
                rValue = self.listOfTexture[nextIndex]
    
            return rValue
    
        def GetPred(self, root, userdata, obj):
            """
            Returns the previous Object to display before arg:'obj'
            """
            rValue = None
            currentObjIndex = self.listOfTexture.index(obj)
            predIndex = currentObjIndex - 1
            if 0 <= predIndex < len(self.listOfTexture):
                rValue = self.listOfTexture[predIndex]
    
            return rValue
    
        def GetId(self, root, userdata, obj):
            """
            Return a unique ID for the element in the TreeView.
            """
            return hash(obj)
    
        def Select(self, root, userdata, obj, mode):
            """
            Called when the user selects an element.
            """
            if mode == c4d.SELECTION_NEW:
                # for tex in self.listOfTexture:
                    # tex.Deselect()
                obj.Select()
            elif mode == c4d.SELECTION_ADD:
                obj.Select()
            elif mode == c4d.SELECTION_SUB:
                obj.Deselect()
    
            
            # i want to call _CalcSum here how ??? ------------------------------------------------------------------------------------------------------------------------------
            """
                MenuCommand ok
                    dialog 
                        RestoreLayout
                            TestDialog ok
            """
            #sum = MenuCommand.dialog.RestoreLayout.TestDialog._CalcSum
            print (TestDialog._CalcSum)
            
    
        def IsSelected(self, root, userdata, obj):
            """
            Returns: True if *obj* is selected, False if not.
            """
            return obj.IsSelected
    
        def SetCheck(self, root, userdata, obj, column, checked, msg):
            """
            Called when the user clicks on a checkbox for an object in a
            `c4d.LV_CHECKBOX` column.
            """
            if checked:
                obj.Select()
            else:
                obj.Deselect()
    
        def IsChecked(self, root, userdata, obj, column):
            """
            Returns: (int): Status of the checkbox in the specified *column* for *obj*.
            """
            if obj.IsSelected:
                return c4d.LV_CHECKBOX_CHECKED | c4d.LV_CHECKBOX_ENABLED
            else:
                return c4d.LV_CHECKBOX_ENABLED
    
        def GetName(self, root, userdata, obj):
            """
            Returns the name to display for arg:'obj', only called for column of type LV_TREE
            """
            return str(obj) # Or obj.texturePath
    
        def DrawCell(self, root, userdata, obj, col, drawinfo, bgColor):
            """
            Draw into a Cell, only called for column of type LV_USER
            """
            if col == ID_OTHER:
                #name = obj.otherData
                name = obj.NiceFileSize()
                geUserArea = drawinfo["frame"]
                w = geUserArea.DrawGetTextWidth(name)
                h = geUserArea.DrawGetFontHeight()
                xpos = drawinfo["xpos"]
                ypos = drawinfo["ypos"] + drawinfo["height"]
                drawinfo["frame"].DrawText(name, xpos, ypos - h * 1.1)
    
        def DoubleClick(self, root, userdata, obj, col, mouseinfo):
            """
            Called when the user double-clicks on an entry in the TreeView.
    
            Returns:
              (bool): True if the double-click was handled, False if the
                default action should kick in. The default action will invoke
                the rename procedure for the object, causing `SetName()` to be
                called.
            """
            #c4d.gui.MessageDialog("You clicked on " + str(obj))
            return True
    
        def DeletePressed(self, root, userdata):        
            "Called when a delete event is received."
            for tex in reversed(self.listOfTexture):
                if tex.IsSelected:
                    self.listOfTexture.remove(tex)
            
    
    class TestDialog(c4d.gui.GeDialog):
        _treegui = None # Our CustomGui TreeView
        _listView = ListView() # Our Instance of c4d.gui.TreeViewFunctions
        
        
        def CreateLayout(self):
            #create the menu
            self.MenuFlushAll()
            #Bookmarks menu
            self.MenuSubBegin("Bookmarks")
            #self.MenuAddString(MNU_BOOKMARK_1["id"], MNU_BOOKMARK_1["name"])
            #self.MenuAddString(MNU_BOOKMARK_2["id"], MNU_BOOKMARK_2["name"])
            
            for addid, folderlink in enumerate(ID_BOOKMARKLIST):
                self.MenuAddString(addid+500, folderlink) # we add 500 to be out of range of common IDs we subtract 500 below in the comand section
            self.MenuSubEnd()    
    
            if self.GroupBegin(id=1, flags=c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, rows=5, cols=1, groupflags=c4d.BORDER_GROUP_IN):
                self.GroupBorderSpace(5, 5, 5, 5)
                self.GroupBorderNoTitle(borderstyle=c4d.BORDER_BLACK)
    
                # Folder Selection group with title
                #----------------------------------------------------------
                if self.GroupBegin(id=11, flags=c4d.BFH_SCALEFIT, rows=1, cols=1, title="Folderpath", groupflags=c4d.BORDER_GROUP_IN):
                    self.GroupBorderSpace(5, 5, 5, 5)
                    self.GroupBorder(c4d.BORDER_ROUND)
                    
                    # Colored Border group
                    #----------------------------------------------------------
                    if self.GroupBegin(id=ID_COLOREDBORDER, flags=c4d.BFH_SCALEFIT, rows=1, cols=3, groupflags=c4d.BORDER_GROUP_OUT):
                        self.GroupBorderNoTitle(c4d.BORDER_ACTIVE_2)
                        self.AddEditText(id=ID_PATHSTRING, flags=c4d.BFH_LEFT | c4d.BFH_SCALEFIT, initw=432, inith=0, editflags=c4d.EDITTEXT_HELPTEXT)
                        self.SetString(id=ID_PATHSTRING, value="Choose folder with dialog or paste the path here.", flags=c4d.EDITTEXT_HELPTEXT )
                        self.AddButton(id=ID_FOLDERSELECTION_SYSTEM, flags=c4d.BFV_FIT | c4d.BFH_FIT | c4d.BFH_RIGHT, name="Select Folder")
                        self.AddButton(id=ID_SCANCONTENT, flags=c4d.BFV_FIT | c4d.BFH_FIT | c4d.BFH_RIGHT, name="Load folder content")
                        self.GroupEnd()            
                    self.GroupEnd()
                    
            if self.GroupBegin(ID_INFOBOX, cols=1, flags=c4d.BFH_SCALEFIT, initw=0, inith=0 ,title=""):
                self.AddStaticText(212, flags=c4d.BFV_CENTER | c4d.BFV_SCALE | c4d.BFH_CENTER | c4d.BFH_SCALE, initw=0, inith=0, name="Info box")
                self.GroupEnd()
    
            if self.GroupBegin(999, cols=1, flags=c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, initw=0, inith=0 ,title="Files in Folder:"):
                self.GroupBorderSpace(5, 5, 5, 5)
                self.GroupBorder(c4d.BORDER_ROUND) 
                
                self.AddCheckbox( ID_SELECTALL, flags=c4d.BFH_LEFT, initw=0, inith=0 , name="Select All")
                
                # Create the TreeView GUI.
                #----------------------------------------------------------
                customgui = c4d.BaseContainer()
                #customgui.SetBool(c4d.TREEVIEW_BORDER, c4d.BORDER_THIN_IN )
                customgui.SetBool(c4d.TREEVIEW_BORDER, c4d.BORDER_NONE | c4d.BORDER_GROUP_IN)
                customgui.SetBool(c4d.TREEVIEW_HAS_HEADER, True) # True if the tree view may have a header line.
                customgui.SetBool(c4d.TREEVIEW_HIDE_LINES, True) # True if no lines should be drawn.
                customgui.SetBool(c4d.TREEVIEW_MOVE_COLUMN, False) # True if the user can move the columns.
                customgui.SetBool(c4d.TREEVIEW_RESIZE_HEADER, True) # True if the column width can be changed by the user.
                customgui.SetBool(c4d.TREEVIEW_FIXED_LAYOUT, True) # True if all lines have the same height.
                customgui.SetBool(c4d.TREEVIEW_ALTERNATE_BG, True) # Alternate background per line.
                customgui.SetBool(c4d.TREEVIEW_CURSORKEYS, True) # True if cursor keys should be processed.
                customgui.SetBool(c4d.TREEVIEW_NOENTERRENAME, True) # Suppresses the rename popup when the user presses enter.
                customgui.SetBool(c4d.TREEVIEW_NO_DELETE, True) # Disable Delete Message Callback completely for backspace and delete.
                #customgui.SetBool(c4d.TREEVIEW_ADDROW, True) # Show an add new column row at the bottom of the list.
                
                self._treegui = self.AddCustomGui( 1000, c4d.CUSTOMGUI_TREEVIEW, "", c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 400, 100, customgui) # minw, minh 
                if not self._treegui:
                    print ("[ERROR]: Could not create TreeView")
                    return False
            
                self.GroupEnd()
    
            if self.GroupBegin(ID_SUMBOX, cols=2, flags=c4d.BFH_SCALEFIT, initw=0, inith=0, title="Filesizesum:"):
                self.GroupBorderSpace(5, 5, 5, 5)
                self.GroupBorderNoTitle(borderstyle=c4d.BORDER_BLACK)
                self.AddStaticText(332, flags=c4d.BFV_CENTER | c4d.BFV_SCALE | c4d.BFH_CENTER | c4d.BFH_SCALE, initw=0, inith=0, name="Selected: ")
                self.AddStaticText(333, flags=c4d.BFV_CENTER | c4d.BFV_SCALE | c4d.BFH_RIGHT | c4d.BFH_SCALE, initw=0, inith=0, name="Filesize Sum: ")
                self.GroupEnd()
    
            
            # OK Cancel
            #----------------------------------------------------------
            if self.GroupBegin(id=3, flags=c4d.BFV_BOTTOM | c4d.BFH_SCALEFIT, inith=25, rows=1, cols=2, title="", groupflags=c4d.BORDER_GROUP_IN):
                #self.GroupBorderSpace(5, 5, 5, 5)
                self.GroupBorderNoTitle(borderstyle=c4d.BORDER_NONE) # BORDER_NONE BORDER_BLACK
                self.AddButton(ID_CLOSE, flags=c4d.BFH_LEFT | c4d.BFV_SCALEFIT | c4d.BFH_SCALE | c4d.BFV_BOTTOM, name="Close")
                self.AddButton(ID_IMPORT, flags=c4d.BFH_RIGHT | c4d.BFV_SCALEFIT | c4d.BFH_SCALE | c4d.BFV_BOTTOM, name="Import")
                self.GroupEnd()
            
            self.GroupEnd() # main group end
            
            # self.AddButton(1001, c4d.BFH_CENTER, name="Add")
    
            return True
    
        def InitValues(self):        
            self.folderpath = None
        
            # Initialize the column layout for the TreeView.
            layout = c4d.BaseContainer()
            layout.SetLong(ID_CHECKBOX, c4d.LV_CHECKBOX)
            layout.SetLong(ID_NAME, c4d.LV_TREE)
            layout.SetLong(ID_OTHER, c4d.LV_USER)
            self._treegui.SetLayout(3, layout)
    
            # Set the header titles.
            self._treegui.SetHeaderText(ID_CHECKBOX, "Check")
            self._treegui.SetHeaderText(ID_NAME, "File Name")
            self._treegui.SetHeaderText(ID_OTHER, "Filesize (MB)")
            self._treegui.Refresh()
    
            # Set TreeViewFunctions instance used by our CUSTOMGUI_TREEVIEW
            self._treegui.SetRoot(self._treegui, self._listView, None)
            return True
    
    # Change GUI
    # --------------------------------------------------------------------------------------------------------------------------
        def _DrawGroup(self):
            print ("_DrawGroup: ", self.folderpath)
    
            # Flush the content of the group that holds all ours SubDialogs
            self.LayoutFlushGroup(ID_COLOREDBORDER)        
    
            # new content
            if self.folderpath == None or self.folderpath == "":            
                self.GroupBorderNoTitle(c4d.BORDER_ACTIVE_4) # orange
                self.AddEditText(id=ID_PATHSTRING, flags=c4d.BFH_LEFT | c4d.BFH_SCALEFIT, initw=432, inith=0, editflags=c4d.EDITTEXT_HELPTEXT)
                self.SetString(id=ID_PATHSTRING, value="Choose folder with dialog or paste the path here.", flags=c4d.EDITTEXT_HELPTEXT )
                self.AddButton(id=ID_FOLDERSELECTION_SYSTEM, flags=c4d.BFV_FIT | c4d.BFH_FIT | c4d.BFH_RIGHT, name="Select Folder")
                self.AddButton(id=ID_SCANCONTENT, flags=c4d.BFV_FIT | c4d.BFH_FIT | c4d.BFH_RIGHT, name="Load folder content")  
                
                self.LayoutFlushGroup(ID_INFOBOX)
                self.AddStaticText(212, flags=c4d.BFV_CENTER | c4d.BFV_SCALE | c4d.BFH_CENTER | c4d.BFH_SCALE, initw=0, inith=0, name = "Select a path.")
    
            
            elif not os.path.exists(self.folderpath):
                self.GroupBorderNoTitle(c4d.BORDER_ACTIVE_3) # red
                self.AddEditText(id=ID_PATHSTRING, flags=c4d.BFH_LEFT | c4d.BFH_SCALEFIT, initw=432, inith=0, editflags=c4d.EDITTEXT_HELPTEXT)            
                self.SetString(id=ID_PATHSTRING, value=self.folderpath)
                self.AddButton(id=ID_FOLDERSELECTION_SYSTEM, flags=c4d.BFV_FIT | c4d.BFH_FIT | c4d.BFH_RIGHT, name="Select Folder")
                self.AddButton(id=ID_SCANCONTENT, flags=c4d.BFV_FIT | c4d.BFH_FIT | c4d.BFH_RIGHT, name="Load folder content")  
    
                self.LayoutFlushGroup(ID_INFOBOX)
                self.AddStaticText(212, flags=c4d.BFV_CENTER | c4d.BFV_SCALE | c4d.BFH_CENTER | c4d.BFH_SCALE, initw=0, inith=0, name = "Invalid path please check.")
                
            else:
                self.GroupBorderNoTitle(c4d.BORDER_ACTIVE_2)
                self.AddEditText(id=ID_PATHSTRING, flags=c4d.BFH_LEFT | c4d.BFH_SCALEFIT, initw=432, inith=0, editflags=c4d.EDITTEXT_HELPTEXT)            
                self.AddButton(id=ID_FOLDERSELECTION_SYSTEM, flags=c4d.BFV_FIT | c4d.BFH_FIT | c4d.BFH_RIGHT, name="Select Folder")
                self.AddButton(id=ID_SCANCONTENT, flags=c4d.BFV_FIT | c4d.BFH_FIT | c4d.BFH_RIGHT, name="Load folder content")  
                self.SetString(id=ID_PATHSTRING, value=self.folderpath) # flags=c4d.EDITTEXT_HELPTEXT            
                
                self.LayoutFlushGroup(ID_INFOBOX)
                self.AddStaticText(212, flags=c4d.BFV_CENTER | c4d.BFV_SCALE | c4d.BFH_CENTER | c4d.BFH_SCALE, initw=0, inith=0, name = "Good to go.")
    
            # Notifies the content of the Group has changed
            self.LayoutChanged(ID_INFOBOX)
            self.LayoutChanged(ID_COLOREDBORDER)
            
    # -------------------------------------------------------------------------------------------------------------------------- 
        def _ShowSum(self, valuetodisplay=0, selected=0):
            print ("_ShowSum: ")        
            howmanyselected = "Selected: " + str(selected)
            valuetodisplay = "Filesize Sum:  " + str(valuetodisplay) + " MB"
            
            self.LayoutFlushGroup(ID_SUMBOX)
    
            self.GroupBorderSpace(5, 5, 5, 5)
            self.GroupBorderNoTitle(borderstyle=c4d.BORDER_BLACK)
            self.AddStaticText(332, flags=c4d.BFV_CENTER | c4d.BFV_SCALE | c4d.BFH_CENTER | c4d.BFH_SCALE, initw=0, inith=0, name=howmanyselected)
            self.AddStaticText(333, flags=c4d.BFV_CENTER | c4d.BFV_SCALE | c4d.BFH_RIGHT | c4d.BFH_SCALE, initw=0, inith=0, name=valuetodisplay)
            self.LayoutChanged(ID_SUMBOX)
    
        def _CalcSum(self):
            sumselected = 0
            selected = 0
            
            for fileitem in self._listView.listOfTexture:
                if fileitem.IsSelected == True:
                    sumselected += fileitem.otherData
                    selected += 1
            
            self._ShowSum((round(float(sumselected) / 1024.0 / 1024.0, 1)), selected)
            #return (round(float(sumselected) / 1024.0 / 1024.0, 1))
            
    # --------------------------------------------------------------------------------------------------------------------------
        def loadfolder(self):
            self._listView.listOfTexture = list() # flush the list hence we want to load the content only once
        
            # Add data to our DataStructure (ListView)
            newID = len(self._listView.listOfTexture) 
    
            if self.folderpath != None and self.folderpath != ""  and os.path.exists(self.folderpath):                 
                filelist = os.listdir(self.folderpath.decode("utf-8", "strict"))
                filelist.sort()
                for fileid, img in enumerate ( filelist ):
                    #print (img)
                    img = img.encode("utf-8", "strict")
                    #print (img)
                    fullpath = self.folderpath + "\\" + img
                    #print (fullpath)
                    #texsize = round(float(os.path.getsize(fullpath)) / 1024.0 / 1024.0, 1)
                    texsize = os.path.getsize(fullpath)
                    #tex = TextureObject("T{}".format(newID + fileid))                
                    tex = TextureObject(img.format(newID + fileid), texsize) # the object
                    self._listView.listOfTexture.append(tex) # the big list
                    
                    #print (img)
            else:
                print (self.folderpath)
    
            # Refresh the TreeView
            self._treegui.Refresh()    
        
        
        def Command(self, id, msg):
        
            if id == ID_SELECTALL:
                print ("Checkbox Staus: ", self.GetBool(ID_SELECTALL))             
    
                if self.GetBool(ID_SELECTALL) == True:
                    for fileitem in self._listView.listOfTexture:                    
                        fileitem.Select()
                        
                if self.GetBool(ID_SELECTALL) == False:
                    for fileitem in self._listView.listOfTexture:                    
                        fileitem.Deselect()                
    
                self._treegui.Refresh() 
                return True
      
            if 500 <= id <= 550:            
                bigid = int(id-500)
                #print ("Dropdown ID: ", id, ID_BOOKMARKLIST[bigid])
                self.SetString(ID_PATHSTRING, ID_BOOKMARKLIST[bigid])
                self.folderpath = self.GetString(ID_PATHSTRING)
                self._DrawGroup()
                return True            
            
            if id == ID_FOLDERSELECTION_SYSTEM:            
                self.folderpath = c4d.storage.LoadDialog(type=c4d.FILESELECTTYPE_ANYTHING, title='Choose a Folder with the 3D Data to import.', flags=c4d.FILESELECT_DIRECTORY, force_suffix='', def_path='', def_file='')
                self.SetString(ID_PATHSTRING, str(self.folderpath))
                self._DrawGroup()
                return True
                
            if id == ID_SCANCONTENT:
                self.folderpath = self.GetString(ID_PATHSTRING)
                self._DrawGroup()
                self.loadfolder()        
    
            if id == ID_CLOSE:
                self.Close()
                return True
            
            if id == ID_IMPORT:
                self._CalcSum()
                return True
    
            return True
    
        def CoreMessage(self, id, msg):  
        
            if id == c4d.EVMSG_CHANGE:
                print "Scene was Changed"
    
            return gui.GeDialog.CoreMessage(self, id, msg)
    
        def Message(self, id, msg):
        
            if c4d.gui.GetInputState(c4d.BFM_INPUT_KEYBOARD, c4d.KEY_ESC, msg):
                if msg[c4d.BFM_INPUT_VALUE]:
                    #print ("ESC Pressed - closing window.")
                    self.Close()
                    return True
            return gui.GeDialog.Message(self, id, msg)
    
    class MenuCommand(c4d.plugins.CommandData):    
        dialog = None        
    
        def Execute(self, doc):
            if self.dialog is None:
                self.dialog = TestDialog()
            return self.dialog.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID, defaulth=200, defaultw=600)
    
        def RestoreLayout(self, sec_ref):
            if self.dialog is None:
                self.dialog = TestDialog()
            return self.dialog.Restore(PLUGIN_ID, secret=sec_ref)
    
    def main():    
        # Retrieves the icon path
        directory, _ = os.path.split(__file__)
        fn = os.path.join(directory, "res", "cadfile_importer_icon.tif")
    
        if os.path.isfile(fn) :
            # Creates a BaseBitmap
            bmp = c4d.bitmaps.BaseBitmap()
            if bmp is None:
                raise MemoryError("Failed to create a BaseBitmap.")
    
            # Init the BaseBitmap with the icon
            if bmp.InitWith(fn)[0] != c4d.IMAGERESULT_OK:
                #raise MemoryError("Failed to initialize the BaseBitmap.")
                print ("Failed to initialize the BaseBitmap.")
        else:
            print ("Bitmap not Found.", PLUGIN_NAME)
            bmp = None    
            
        try:
            c4d.plugins.RegisterCommandPlugin(  id=PLUGIN_ID, 
                                                str=PLUGIN_NAME,  
                                                info=0, 
                                                icon=bmp, 
                                                help="Lists files of a folder.", 
                                                dat=MenuCommand()
                                                )
        except ValueError:
            print ("Following Plugin could not be registered: ",  PLUGIN_NAME)
    
    if __name__ == "__main__":
        c4d.CallCommand(13957) # clear concole
        main()
    

    PS: I never know in which subforum to put these broad questions ...

    kind regards mogh



  • userdata parameter of the TreeViewFunctions overidden methods can be anything, your dialog for example. ;)



  • hi,

    you could also add your gedialog as a parameter when you create your treeviewfunctions

    something like this.

    import c4d
    import os
    import weakref
    
    
    class Hierarchy(c4d.gui.TreeViewFunctions):
    
      def __init__(self, dlg):
        # Avoid a cyclic reference.
        self._dlg = weakref.ref(dlg)
        # add the code ...
    
    # when you create an instance of your TreeViewFunctions
    data_model = Hierarchy(self)
    
    

    and in your select method you need to call the dialog function like so

    self._dlg()._CalcSum()
    

    Cheers,
    Manuel



  • thank you for your help, I am trying to understand ...

    am I right in the assumption that this is not "clean code" in a pythonic sense ?
    kind regards