QuickTabCustomGui.GetData() is None
-
Hi,
i am confuse about BaseCustomGui.GetData(), my_QuickTabCustomGui.GetData() always return None and SetData() always return False, anyone could tell me how to use it?
hope yout help! -
Hi @mike, thanks for reaching out us.
With regard to your question, I encourage to have a look at the cinema4dsdk on Github examples where on the customgui_string.cpp both methods are properly implemented (see here).
If the example isn't enough to bring you on the right direction, please provide us with some more details (code?) in order to look at your implementation.
Best, Riccardo
-
@r_gigante thank you for your answer,i m misunderstand what it means. And is there any way to get and reset customgui data? return a basecontainer and reset setting,looks like node.setparameter( )?
-
Hi @mike G/SetData come from the BaseCustomGui class and in fact offer only a way to define as low level, most of the time used for the tristate stuff so I would say for most of the time it's does not do what you expect.
Most of the time to manage a CustomGui you have to use directly the method from your custom GUI (in your case QuickTabCustomGui).
May I ask you what you really want to do?
Cheers,
Maxime. -
@m_adam actually i want get my QuickTabCustomGui String count and name str,also reset ,but in Python sdk, only have appendstring() and ClearStrings(),so,i think maybe i can get the cutomgui data (basecontainer or other )and reset data by myself?
-
Actually, you are right and you have to handle this by yourself.
Here is an example how it could work.""" Copyright: MAXON Computer GmbH Author: Maxime Adam Description: - Creates a Modal Dialog displaying a different SubDialog according to the selected entry of the QuickTab. - Demonstrates how to adds, flushes, removes tab interactively. Class/method highlighted: - c4d.gui.QuickTabCustomGui - QuickTabCustomGui.ClearStrings() - QuickTabCustomGui.AppendString() - c4d.gui.GeDialog - GeDialog.CreateLayout() - GeDialog.InitValues() - GeDialog.Command() - GeDialog.HideElement() - GeDialog.RemoveElement() - c4d.gui.SubDialog Compatible: - Win / Mac - R19, R20 """ import c4d # Ids used in our Dialog ID_MAINGROUP = 100000 # ID used for the Group that holds all the other group representing the tab content ID_QUICKTAB_BAR = 110000 # ID for the quicktab customGui ID_QUICKTAB_BASE_GROUP = 120000 # Base ID for each SubDialog BUTTON_PRINT_TEXT = 1200 # ID used for the Print text Button BUTTON_PRINT_SELECTED = 1201 # ID used for the Print Selected Button BUTTON_FLUSH_ALL = 1203 # ID used for the Flush All Button BUTTON_ADD = 1204 # ID used for the Add Button BUTTON_REMOVE = 1205 # ID used for the Remove Button # Id used in our SubDialog CUSTOM_GROUP_ID_TEXT_BASE = 100000 # Defines the ID for the string to be displayed class CustomGroup(c4d.gui.SubDialog): """ A SubDialog to display the passed string, its used as example for the actual content of a Tab """ def __init__(self, data): self._data = data def CreateLayout(self): for i, data in enumerate(self._data): self.AddStaticText(CUSTOM_GROUP_ID_TEXT_BASE + i, c4d.BFH_SCALEFIT, name=data) return True class QuickTabDialogExample(c4d.gui.GeDialog): def __init__(self): self._quickTab = None # Stores the quicktab custom GUI self._tabList = {} # Stores the TabName and the SubDialog that represents each tab of the QuickTab def _DrawQuickTabGroup(self): """ Creates and draws all the SubDialog for each tab, take care it does not hide these according to a selection state. :return: True if success otherwise False. """ # Checks if the quicktab is defined if self._quickTab is None: return False # Flush the content of the group that holds all ours SubDialogs self.LayoutFlushGroup(ID_MAINGROUP) # Iterates over the number of tab to create and attach the correct SubDialog for tabId, (tabName, tabGui) in enumerate(self._tabList.iteritems()): self.AddSubDialog(ID_QUICKTAB_BASE_GROUP + tabId, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 0, 0) self.AttachSubDialog(tabGui, ID_QUICKTAB_BASE_GROUP + tabId) # Notifies the content of the MainGroup has changed self.LayoutChanged(ID_MAINGROUP) return True def GetActiveTab(self): """ Retrieves the current selected tab from the self._quickTab. :return: The tab Id (from the dict) and the name of the selected tab :rtype: (int, str) or (False, False) if fail. """ # Checks if the quicktab is defined if self._quickTab is None: return False, False for tabId, (tabName, tabGui) in enumerate(self._tabList.iteritems()): if self._quickTab.IsSelected(tabId): return tabId, tabName return False, False def DisplayCorrectGroup(self): """ Hides all unused groups and display the correct one. :return: True if success otherwise False. """ # Retrieves the selected tab activeId, activeName = self.GetActiveTab() if activeId is False: return False # Iterates each CustomGui and defines if they are hidden or not for tabId in xrange(len(self._tabList)): toHide = activeId == tabId self.HideElement(ID_QUICKTAB_BASE_GROUP + tabId, not toHide) # Notifies the content of the MainGroup has changed self.LayoutChanged(ID_MAINGROUP) return True def AppendTab(self, tabName, content, active=True): """ Appends a tab to the current quicktab with the associated content to be displayed. :param tabName: The name the tab should have. :type tabName: str :param content: The SubDialog to be drawn/linked when the tab is selected. :type content: c4d.gui.SubDialog :param active: If True, the inserted tab will be selected :type active: bool :return: True if success otherwise False. """ # Checks if the quicktab is defined if self._quickTab is None: return False # Adds the tab entry n the quicktab self._quickTab.AppendString(len(self._tabList), tabName, False) # Updates our current tabList with tabName and the Subdialog to be linked self._tabList.update({tabName: content}) # Retrieves the current selected tab previousActiveId, previousActiveName = self.GetActiveTab() # Draws the quicktab SubDialog (in order to have the new one drawn) self._DrawQuickTabGroup() # Defines which tab should be active if active: self._quickTab.Select(len(self._tabList) - 1, True) else: self._quickTab.Select(previousActiveId, True) # Display only the selected tab and hides all others self.DisplayCorrectGroup() return True def FlushAllTabs(self): """ Removes all tabs and their content from the GUI. :return: True if success otherwise False. """ # Checks if the quicktab is defined if self._quickTab is None: return False # Removes all the tabs self._quickTab.ClearStrings() # Removes all the customGui for tabId in xrange(len(self._tabList)): self.RemoveElement(ID_QUICKTAB_BASE_GROUP + tabId) # Reinitializes the stored tablist to an empty dict self._tabList = {} # Notifies the content of the MainGroup has changed self.LayoutChanged(ID_MAINGROUP) return True def RemoveTab(self, tabNameToRemove): """ Removes a tab by its name :param tabNameToRemove: The tab to remove. :type tabNameToRemove: str :return: True if success otherwise False. """ # Checks if the quicktab is defined if self._quickTab is None: return False # Copies the tabList newDict = dict(self._tabList) # Removes teh entry we want to delete del newDict[tabNameToRemove] # Removes all groups self.FlushAllTabs() # Re-adds all the one from our copy for tabName, tabGui in newDict.iteritems(): self.AppendTab(tabName, tabGui) return True def CreateLayout(self): """ This Method is called automatically when Cinema 4D Create the Layout (display) of the Dialog. """ # Creates a QuickTab Custom Gui bc = c4d.BaseContainer() bc.SetBool(c4d.QUICKTAB_BAR, False) bc.SetBool(c4d.QUICKTAB_SHOWSINGLE, True) bc.SetBool(c4d.QUICKTAB_NOMULTISELECT, True) self._quickTab = self.AddCustomGui(ID_QUICKTAB_BAR, c4d.CUSTOMGUI_QUICKTAB, '', c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 0, 0, bc) # Creates a group that will contain all the group representing each tab self.GroupBegin(ID_MAINGROUP, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 0, 0, '', 0) self.GroupEnd() # Creates a group with 5 button in order to do some operation with the QuickTab CustomGUI if self.GroupBegin(0, c4d.BFH_SCALEFIT, 5, 1, '', 0): self.AddButton(BUTTON_PRINT_TEXT, c4d.BFH_SCALEFIT, name="Print text") self.AddButton(BUTTON_PRINT_SELECTED, c4d.BFH_SCALEFIT, name="Print Selected") self.AddButton(BUTTON_FLUSH_ALL, c4d.BFH_SCALEFIT, name="Flush All") self.AddButton(BUTTON_ADD, c4d.BFH_SCALEFIT, name="Add") self.AddButton(BUTTON_REMOVE, c4d.BFH_SCALEFIT, name="Remove") self.GroupEnd() return True def InitValues(self): """ This Method is called automatically after the GUI is initialized. """ # Creates the first Tab cg1 = CustomGroup(["This is the first Tab", "Just dummy text here"]) self.AppendTab("First Tab", cg1, False) # Creates the second Tab cg2 = CustomGroup(["This is the second Tab", "Just another dummy text here"]) self.AppendTab("Second Tab", cg2, False) return True def Command(self, id, msg): """ This Method is called automatically when the user clicks on a gadget and/or changes its value this function will be called. It is also called when a string menu item is selected. :param id: The ID of the gadget that triggered the event. :param msg: The original message container :return: False if there was an error, otherwise True. """ # If the user interacts with the quicktab, we make sure to display the CustomGUI linked to the active one if id == ID_QUICKTAB_BAR and self._quickTab: self.DisplayCorrectGroup() return True # Displays all the Tab name if id == BUTTON_PRINT_TEXT: print [key for key in self._tabList] return True # Displays the ID and name of the selected tab if id == BUTTON_PRINT_SELECTED: print self.GetActiveTab() # Removes all tabs if id == BUTTON_FLUSH_ALL: self.FlushAllTabs() # Adds a new Tab to the quicktab if id == BUTTON_ADD: cg3 = CustomGroup(["This is the third Tab"]) self.AppendTab("Third Tab", cg3, False) # Removes the first tab of the quicktab if id == BUTTON_REMOVE: self.RemoveTab("First Tab") return True # Main function def main(): # Initializes a QuickTabDialogExample Dialog diag = QuickTabDialogExample() # Opens the Dialog in modal mode diag.Open(dlgtype=c4d.DLG_TYPE_MODAL, defaultw=400, defaulth=400) # Execute main() if __name__ == '__main__': main()
If you have any question on the previous code, please let me know.
Cheers,
Maxime. -
@m_adam thank you for your answer from the code, it similar to what i already try, but this way looks like not a perfect solution. actually after read most c4d gui sdk and write some examples, i think maybe c4d should update gui model? sometimes it not flexible. just my personal thoughts, don't mind : ) expect python 3.x and pyside2 coming : )