Solved CUSTOMGUI_QUICKTAB trigger twice when click

Hello guys,
I want to achieve a Cycle button gui with python ( like subdivide UVs in a SDS ) , I find CUSTOMGUI_QUICKTAB provide a UI like this , but when I test my dialog , I click on a quicktab , it return id twice, but when I print something , it works well ( I just want keep this gui but not any sub dlg , and do some stuff when change a tab button like refresh ua and treeview , it executed twice is too expensive ) so what's wrong with my codes?

[win 11@22H2 , c4d 2023.2.0]

import c4d

ID_QUICKTAB_BAR = 110000  # ID for the quicktab customGui

class QuickTabDialogExample(c4d.gui.GeDialog):

    def __init__(self):
        self._quickTab = None  # Stores the quicktab custom GUI

    def CreateLayout(self):

        bc = c4d.BaseContainer()
        bc.SetBool(c4d.QUICKTAB_BAR, 0)
        bc.SetBool(c4d.QUICKTAB_SHOWSINGLE, True)
        bc.SetBool(c4d.QUICKTAB_NOMULTISELECT, 1)
        self._quickTab = self.AddCustomGui(ID_QUICKTAB_BAR, c4d.CUSTOMGUI_QUICKTAB, '',
                                           c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 0, 0, bc)
        self._quickTab.AppendString(0, "1", 1)
        self._quickTab.AppendString(1, "2", 0)
        self._quickTab.AppendString(2, "3", 0)

        self.AddButton(50, c4d.BFH_SCALEFIT, name="Print Selected")
        return True

    def Command(self, id, msg):
        
        print(id)

        # Displays the ID and name of the selected tab
        if id == 50:
            if self._quickTab.IsSelected(0):
                print("1 select")
            if self._quickTab.IsSelected(1):
                print("2 select")
            if self._quickTab.IsSelected(2):
                print("3 select")
            
        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=0, defaulth=0)


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

Hi @Dunhou thanks for reaching us, looks like it was always the case at least I can reproduce it up to 21, and I stopped to check for earlier version. I opened a bug report about it, the only workaround would be track yourself the selection state and compare it each time.
Find bellow a prototype:

import c4d
import dataclasses 

ID_QUICKTAB_BAR = 110000

@dataclasses.dataclass
class Entry:
    entryId: int
    entryName: str
    selectionState: bool

class QuickTabDialogExample(c4d.gui.GeDialog):

    def __init__(self):
        self.entries = []
        self.entriesHash = 0
        self._quickTab = None

    def CreateLayout(self):

        bc = c4d.BaseContainer()
        bc.SetBool(c4d.QUICKTAB_BAR, 0)
        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)
        
        self.entries.append(Entry(10001, "1", True))
        self.entries.append(Entry(10002, "2", False))
        self.entries.append(Entry(10003, "3", False))
        
        self.entriesHash = hash(str(self.entries))
        
        for entry in self.entries:
            self._quickTab.AppendString(entry.entryId, entry.entryName, entry.selectionState)

        self.AddButton(10050, c4d.BFH_SCALEFIT, name="Print Selected")
        return True

    def Command(self, id, msg):

        # Displays the ID and name of the selected tab
        if id == 10050:
            x = self._quickTab.GetData()
            if self._quickTab.IsSelected(10001):
                print("1 select")
            if self._quickTab.IsSelected(10002):
                print("2 select")
            if self._quickTab.IsSelected(10003):
                print("3 select")
                
        elif id == ID_QUICKTAB_BAR and self._quickTab:
            for entry in self.entries:
                entry.selectionState = self._quickTab.IsSelected(entry.entryId)
            
            newSelectionState = hash(str(self.entries))
            if newSelectionState != self.entriesHash:
                self.entriesHash = newSelectionState
                print("Selection changed")


        return True


# Main function
def main():
    diag = QuickTabDialogExample()
    diag.Open(dlgtype=c4d.DLG_TYPE_MODAL, defaultw=0, defaulth=0)


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

Cheers,
Maxime.

@m_adam Thanks man! this @dataclasses.dataclass decorator is pretty handy , new knowledge incoming:blush:

And maybe some similar bug I have seen before , but I don't remember what it is (and even didn't know it is a bug or my bad coding:face_with_head_bandage: ) , if I met some similar bugs I will update the topic , but now let's hope it will be fixed next release .

Thanks for your help again

Cheers~