class PropertyEditor(QWidget): # Signals insertionModeStarted = pyqtSignal(str) insertionModeEnded = pyqtSignal() insertionPropertiesChanged = pyqtSignal(object) editPropertiesChanged = pyqtSignal(object) def __init__(self, config, parent=None): QWidget.__init__(self, parent) self._class_config = {} self._class_items = {} self._class_prototypes = {} self._attribute_handlers = {} self._handler_factory = AttributeHandlerFactory() self._setupGUI() # Add label classes from config for label in config: self.addLabelClass(label) def onModelChanged(self, new_model): attrs = set([ k for k, v in self._attribute_handlers.items() if v.autoAddEnabled() ]) if len(attrs) > 0: start = time.time() attr2vals = {} for item in new_model.iterator(AnnotationModelItem): for attr in attrs: if attr in item: if attr not in attr2vals: attr2vals[attr] = set((item[attr], )) else: attr2vals[attr] |= set((item[attr], )) diff = time.time() - start LOG.info("Extracted annotation values from model in %.2fs" % diff) for attr, vals in attr2vals.items(): h = self._attribute_handlers[attr] for val in vals: h.addValue(val, True) def addLabelClass(self, label_config): # Check label configuration if 'attributes' not in label_config: raise ImproperlyConfigured("Label with no 'attributes' dict found") attrs = label_config['attributes'] if 'class' not in attrs: raise ImproperlyConfigured("Labels must have an attribute 'class'") label_class = attrs['class'] if label_class in self._class_config: raise ImproperlyConfigured( "Label with class '%s' defined more than once" % label_class) # Store config self._class_config[label_class] = label_config # Parse configuration and create handlers and item self.parseConfiguration(label_class, label_config) # Add label class button button_text = label_config['text'] button = QPushButton(button_text, self) button.setCheckable(True) button.setFlat(True) button.clicked.connect(bind(self.onClassButtonPressed, label_class)) self._class_buttons[label_class] = button self._classbox_layout.addWidget(button) # Add hotkey if 'hotkey' in label_config: hotkey = QShortcut(QKeySequence(label_config['hotkey']), self) hotkey.activated.connect(button.click) self._class_shortcuts[label_class] = hotkey def parseConfiguration(self, label_class, label_config): attrs = label_config['attributes'] # Add prototype item for insertion self._class_items[label_class] = AnnotationModelItem( {'class': label_class}) # Create attribute handler widgets or update their values for attr, vals in attrs.items(): if attr in self._attribute_handlers: self._attribute_handlers[attr].updateValues(vals) else: handler = self._handler_factory.create(attr, vals) if handler is None: self._class_items[label_class][attr] = vals else: self._attribute_handlers[attr] = handler for attr in attrs: if attr in self._attribute_handlers: self._class_items[label_class].update( self._attribute_handlers[attr].defaults()) def getHandler(self, attribute): if attribute in self._attribute_handlers: return self._attribute_handlers[attribute] else: return None def getLabelClassAttributes(self, label_class): return self._class_config[label_class]['attributes'].keys() def onClassButtonPressed(self, label_class): if self._class_buttons[label_class].isChecked(): self.startInsertionMode(label_class) else: self.endInsertionMode() def startInsertionMode(self, label_class): self.endInsertionMode(False) for lc, button in self._class_buttons.items(): button.setChecked(lc == label_class) LOG.debug("Starting insertion mode for %s" % label_class) self._label_editor = LabelEditor([self._class_items[label_class]], self, True) self._layout.insertWidget(1, self._label_editor, 0) self.insertionModeStarted.emit(label_class) def endInsertionMode(self, uncheck_buttons=True): if self._label_editor is not None: LOG.debug("Ending insertion/edit mode") self._label_editor.hide() self._layout.removeWidget(self._label_editor) self._label_editor = None if uncheck_buttons: self.uncheckAllButtons() self.insertionModeEnded.emit() def uncheckAllButtons(self): for lc, button in self._class_buttons.items(): button.setChecked(False) def markEditButtons(self, label_classes): for lc, button in self._class_buttons.items(): button.setFlat(lc not in label_classes) def currentEditorProperties(self): if self._label_editor is None: return None else: return self._label_editor.currentProperties() def startEditMode(self, model_items): # If we're in insertion mode, ignore empty edit requests if self._label_editor is not None and self._label_editor.insertionMode() \ and len(model_items) == 0: return self.endInsertionMode() LOG.debug("Starting edit mode for items: %s" % model_items) self._label_editor = LabelEditor(model_items, self) self.markEditButtons(self._label_editor.labelClasses()) self._layout.insertWidget(1, self._label_editor, 0) def _setupGUI(self): self._class_buttons = {} self._class_shortcuts = {} self._label_editor = None # Label class buttons self._classbox = QGroupBox("Labels", self) self._classbox_layout = FloatingLayout() self._classbox.setLayout(self._classbox_layout) # Global widget self._layout = MyVBoxLayout() self.setLayout(self._layout) self._layout.addWidget(self._classbox, 0) self._layout.addStretch(1)
class PropertyEditor(QWidget): # Signals insertionModeStarted = pyqtSignal(str) insertionModeEnded = pyqtSignal() insertionPropertiesChanged = pyqtSignal(object) editPropertiesChanged = pyqtSignal(object) def __init__(self, config, parent=None): QWidget.__init__(self, parent) self._class_config = {} self._class_items = {} self._class_prototypes = {} self._attribute_handlers = {} self._handler_factory = AttributeHandlerFactory() self._setupGUI() # Add label classes from config for label in config: self.addLabelClass(label) def onModelChanged(self, new_model): attrs = set([k for k, v in self._attribute_handlers.items() if v.autoAddEnabled()]) if len(attrs) > 0: start = time.time() attr2vals = {} for item in new_model.iterator(AnnotationModelItem): for attr in attrs: if attr in item: if attr not in attr2vals: attr2vals[attr] = set((item[attr], )) else: attr2vals[attr] |= set((item[attr], )) diff = time.time() - start LOG.info("Extracted annotation values from model in %.2fs" % diff) for attr, vals in attr2vals.items(): h = self._attribute_handlers[attr] for val in vals: h.addValue(val, True) def addLabelClass(self, label_config): # Check label configuration if 'attributes' not in label_config: raise ImproperlyConfigured("Label with no 'attributes' dict found") attrs = label_config['attributes'] if 'class' not in attrs: raise ImproperlyConfigured("Labels must have an attribute 'class'") label_class = attrs['class'] if label_class in self._class_config: raise ImproperlyConfigured("Label with class '%s' defined more than once" % label_class) # Store config self._class_config[label_class] = label_config # Parse configuration and create handlers and item self.parseConfiguration(label_class, label_config) # Add label class button button = QPushButton(label_class, self) button.setCheckable(True) button.setFlat(True) button.clicked.connect(bind(self.onClassButtonPressed, label_class)) self._class_buttons[label_class] = button self._classbox_layout.addWidget(button) # Add hotkey if 'hotkey' in label_config: hotkey = QShortcut(QKeySequence(label_config['hotkey']), self) hotkey.activated.connect(button.click) self._class_shortcuts[label_class] = hotkey def parseConfiguration(self, label_class, label_config): attrs = label_config['attributes'] # Add prototype item for insertion self._class_items[label_class] = AnnotationModelItem({ 'class': label_class }) # Create attribute handler widgets or update their values for attr, vals in attrs.items(): if attr in self._attribute_handlers: self._attribute_handlers[attr].updateValues(vals) else: handler = self._handler_factory.create(attr, vals) if handler is None: self._class_items[label_class][attr] = vals else: self._attribute_handlers[attr] = handler for attr in attrs: if attr in self._attribute_handlers: self._class_items[label_class].update(self._attribute_handlers[attr].defaults()) def getHandler(self, attribute): if attribute in self._attribute_handlers: return self._attribute_handlers[attribute] else: return None def getLabelClassAttributes(self, label_class): return self._class_config[label_class]['attributes'].keys() def onClassButtonPressed(self, label_class): if self._class_buttons[label_class].isChecked(): self.startInsertionMode(label_class) else: self.endInsertionMode() def startInsertionMode(self, label_class): self.endInsertionMode(False) for lc, button in self._class_buttons.items(): button.setChecked(lc == label_class) LOG.debug("Starting insertion mode for %s" % label_class) self._label_editor = LabelEditor([self._class_items[label_class]], self, True) self._layout.insertWidget(1, self._label_editor, 0) self.insertionModeStarted.emit(label_class) def endInsertionMode(self, uncheck_buttons=True): if self._label_editor is not None: LOG.debug("Ending insertion/edit mode") self._label_editor.hide() self._layout.removeWidget(self._label_editor) self._label_editor = None if uncheck_buttons: self.uncheckAllButtons() self.insertionModeEnded.emit() def uncheckAllButtons(self): for lc, button in self._class_buttons.items(): button.setChecked(False) def markEditButtons(self, label_classes): for lc, button in self._class_buttons.items(): button.setFlat(lc not in label_classes) def currentEditorProperties(self): if self._label_editor is None: return None else: return self._label_editor.currentProperties() def startEditMode(self, model_items): # If we're in insertion mode, ignore empty edit requests if self._label_editor is not None and self._label_editor.insertionMode() \ and len(model_items) == 0: return self.endInsertionMode() LOG.debug("Starting edit mode for items: %s" % model_items) self._label_editor = LabelEditor(model_items, self) self.markEditButtons(self._label_editor.labelClasses()) self._layout.insertWidget(1, self._label_editor, 0) def _setupGUI(self): self._class_buttons = {} self._class_shortcuts = {} self._label_editor = None # Label class buttons self._classbox = QGroupBox("Labels", self) self._classbox_layout = FloatingLayout() self._classbox.setLayout(self._classbox_layout) # Global widget self._layout = MyVBoxLayout() self.setLayout(self._layout) self._layout.addWidget(self._classbox, 0) self._layout.addStretch(1)
class PropertyEditor(QWidget): # Signals insertionModeStarted = pyqtSignal(str, str, str) insertionModeEnded = pyqtSignal() insertionPropertiesChanged = pyqtSignal(object) editPropertiesChanged = pyqtSignal(object) checkboxStateChangedSignal = pyqtSignal(str, object) _optionsCheckboxStateChangedSignal = pyqtSignal(str, object) def setAnnotationScene(self, annotationScene): self._scene = annotationScene def setOptionStateChangedSignalSlot(self, checkboxStateChangedSignalSlot): if checkboxStateChangedSignalSlot is not None: self.checkboxStateChangedSignal.connect( checkboxStateChangedSignalSlot) self._optionsCheckboxStateChangedSignal.connect( self.onInserterButtonOptionChanged) # set enable status for the checkbox group which is attached to inserterButton def enableCheckboxGroup(self, inserterButtonName, enabled=True): widgetsInfo = self._widgets_dict.get(inserterButtonName, None) if not widgetsInfo: return if widgetsInfo[1]: # this button has an attachedCheckboxGroup attachedCheckboxGroupWidget = widgetsInfo[1] attachedCheckboxGroupWidget.enableAll(enabled) # set check status for one specific checkbox which is attached to inserterButton def setCheckedCheckbox(self, inserterButtonName, checkBoxName, checked=True): widgetsInfo = self._widgets_dict.get(inserterButtonName, None) # print "inserterButtonName {} _widgets_dict {} checkBoxName {} checked {} ...".format(inserterButtonName, self._widgets_dict, checkBoxName, checked) if not widgetsInfo: return if widgetsInfo[1]: # this button has an attachedCheckboxGroup attachedCheckboxGroupWidget = widgetsInfo[1] attachedCheckboxGroupWidget.setCheckedCheckbox( checkBoxName, checked) # set check status for some specific checkboxs which are attached to inserterButton def setCheckedCheckboxs(self, inserterButtonName, checkBoxNamesList, checked=True): widgetsInfo = self._widgets_dict.get(inserterButtonName, None) if not widgetsInfo: return if widgetsInfo[1]: # this button has an attachedCheckboxGroup attachedCheckboxGroupWidget = widgetsInfo[1] attachedCheckboxGroupWidget.setCheckedCheckboxs( checkBoxNamesList, checked) # get names list of all checkboxs in the checkbox group which is attached to inserterButton def getCheckboxsName(self, inserterButtonName, enabled=True): widgetsInfo = self._widgets_dict.get(inserterButtonName, None) if not widgetsInfo: return if widgetsInfo[1]: # this button has an attachedCheckboxGroup attachedCheckboxGroupWidget = widgetsInfo[1] return attachedCheckboxGroupWidget.get_checkboxs_name() return None def __init__(self, config, idName, displayName, groupBoxName, parent=None): QWidget.__init__(self, parent) self._inserters_modelitems = { } # dict. { inserter_class_name : AnnotationModelItem, ...}. Note that, inserter_class_name is not always equal to inserter_button_name, for those buttons with attached options. self._inserters_guiitems = { } # dict. { inserter_class_name : (inserter_creator_method, inserted_item_creator_method) } self._idName = idName self._groupBoxName = groupBoxName self._displayName = displayName self._scene = None self._current_toinsert_inserterClassName = None self._current_is_insert_mode = False self._widgets_dict = { } # dict. { inserter_button_name :[buttonWidget, buttonAttachedOptionsWidget, buttonName], ....} self._setupGUI(self._groupBoxName) # Add label classes from config for buttonConfig in config: self.addButton(buttonConfig) # print "self._inserters_guiitems = {}".format(self._inserters_guiitems) def onModelChanged(self, new_model): pass def addButton(self, buttonConfig): # LOG.info("addLabelClass with buttonConfig {} ...".format(buttonConfig)) # Check label configuration if 'attributes' not in buttonConfig: raise ImproperlyConfigured("Label with no 'attributes' dict found") inserter_creator_method = buttonConfig['inserter'] inserted_item_creator_method = buttonConfig['item'] attrs = buttonConfig['attributes'] # LOG.info("buttonConfig['attributes'] {} type {} ...".format(buttonConfig['attributes'], type(buttonConfig['attributes']))) if config.METADATA_LABELCLASS_TOKEN not in attrs: raise ImproperlyConfigured( "Labels must have an attribute config.METADATA_LABELCLASS_TOKEN" ) label_class = attrs[config.METADATA_LABELCLASS_TOKEN] # LOG.info("buttonConfig['attributes'][config.METADATA_LABELCLASS_TOKEN] {} type {} ...".format(attrs[config.METADATA_LABELCLASS_TOKEN], type(attrs[config.METADATA_LABELCLASS_TOKEN]))) if label_class in self._inserters_modelitems: raise ImproperlyConfigured( "Label with class '%s' defined more than once" % label_class) # Add INSERTER button displaytext = attrs['displaytext'] buttonName = label_class button = QPushButton(displaytext, self) optionInfo = attrs.get('optioninfo', None) # print "button {}: option {}".format(buttonName, optionInfo) buttonOptionsWidget = None buttonDisplayColor = None tmp = [ o.get(default_config.METADATA_DISPLAYCOLOR_TOKEN, None) for o in optionInfo['option'] if o.get(config.METADATA_IS_DEFAULT_TOKEN, False) ][0] if optionInfo else None buttonDisplayColor = tmp if tmp else optionInfo['option'][0].get( default_config.METADATA_DISPLAYCOLOR_TOKEN, None) if optionInfo else attrs.get( default_config.METADATA_DISPLAYCOLOR_TOKEN, None) # LOG.info(u"buttonConfig['attributes'] = {}, displaytext = {}, displayColor = {}".format(attrs, displaytext, buttonDisplayColor)) # ==== zx add @ 20161114 to display button with color configured by user ==== txtColor = None if buttonDisplayColor is not None: qtColor, hexColor = utils.getColorDesc(buttonDisplayColor) rgba = utils.hexColorStrToRGBA(hexColor) distance = math.sqrt((rgba[0] - 255)**2 + (rgba[1] - 255)**2 + (rgba[2] - 255)**2) txtColor = '#000000' if distance > config.GUI_COLOR_TAG_TEXT_BLACKWHITE_TOGGLE_THRESHOLD else '#ffffff' buttonDisplayColor = hexColor[0:8] # LOG.info(u"buttonDisplayColor = {} txtColor = {}, qtColor = {} hexColor = {}".format(buttonDisplayColor, txtColor, qtColor, hexColor )) # print (u"buttonDisplayColor = {} txtColor = {}, qtColor = {} hexColor = {}".format(buttonDisplayColor, txtColor, qtColor, hexColor )) # print "button {} buttonDisplayColor {} ...".format(buttonName, buttonDisplayColor) utils.set_qobj_stylesheet( button, 'QPushButton', widgetBackgroundColor=None, widgetTextColor=None, widgetBackgroundColorWhenChecked=buttonDisplayColor, widgetTextColorWhenChecked=txtColor) # ========================== zx add end ============================ button.clicked.connect(bind(self.onClassButtonPressed, label_class)) # Add hotkey if 'hotkey' in buttonConfig: hotkey = QShortcut(QKeySequence(buttonConfig['hotkey']), self) hotkey.activated.connect(button.click) self._class_shortcuts[label_class] = hotkey # print "{} is set hotkey {} {}".format(label_class, buttonConfig['hotkey'], hotkey) if optionInfo: optionListName = optionInfo['name'] optionListText = optionInfo['displaytext'] option = optionInfo['option'] buttonOptionsWidget = AttachedCheckboxGroupWidget( buttonName, optionListName, optionListText, True, option, self._optionsCheckboxStateChangedSignal, parent=None) isDefaultOption = False for o in option: new_class = o.get('tag', None) if new_class: # Add prototype mdoelItem for insertion mi = {config.METADATA_LABELCLASS_TOKEN: new_class} mi['displaytext'] = o.get('displaytext', new_class) self._inserters_modelitems[ new_class] = AnnotationModelItem(mi) self._inserters_guiitems[new_class] = ( inserter_creator_method, inserted_item_creator_method) # print "addButton.....self._inserters_guiitems[{}] = {}".format(new_class, (inserter_creator_method, inserted_item_creator_method)) for key, val in o.iteritems(): if key != 'tag': self._inserters_modelitems[new_class][key] = val else: attrs = buttonConfig['attributes'] # Add prototype mdoelItem for insertion mi = {config.METADATA_LABELCLASS_TOKEN: label_class} mi['displaytext'] = attrs.get('displaytext', label_class) self._inserters_modelitems[label_class] = AnnotationModelItem(mi) self._inserters_guiitems[label_class] = ( inserter_creator_method, inserted_item_creator_method) # update their values for key, val in attrs.iteritems(): self._inserters_modelitems[label_class][key] = val # LOG.info("self._inserters_modelitems[{}][{}] = {}".format(label_class, key, val)) self._widgets_dict[label_class] = [button, buttonOptionsWidget] # print "self._widgets_dict [ {} ] = {}".format(label_class, button) button.setCheckable(True) utils.set_qobj_stylesheet( self._widgets_dict[label_class][0], 'QPushButton', widgetBackgroundColor=None, widgetTextColor=None, widgetBackgroundColorWhenChecked=buttonDisplayColor, widgetTextColorWhenChecked=txtColor) if buttonOptionsWidget: # self._layout.addWidget(button) self._inserterButtonGroup_layout.addWidget(button) self._layout.addWidget(buttonOptionsWidget) else: self._inserterButtonGroup_layout.addWidget(button) def onClassButtonPressed(self, pressedButtonName): # print "onClassButtonPressed ... button {} isChecked !".format(pressedButtonName) inserterClassName = pressedButtonName if pressedButtonName not in self._widgets_dict.keys(): # check whether passed-in pressedButtonName argument is an checkbox option name for kk, vv in self._widgets_dict.iteritems(): buttonOptionsWidget = vv[1] if vv else None if buttonOptionsWidget: optionsName = buttonOptionsWidget.get_checkboxs_name() if pressedButtonName in optionsName: pressedButtonName = kk # print "pressedButtonName ============ {}".format(kk) if self._widgets_dict[pressedButtonName][0].isChecked(): if not self._scene._image_item: self._widgets_dict[pressedButtonName][0].setChecked(False) return checkedOption = None if self._widgets_dict[pressedButtonName][1]: buttonOptionsWidget = self._widgets_dict[pressedButtonName][1] checkedOptionsNameList = buttonOptionsWidget.get_checked_widgets_name( ) if not checkedOptionsNameList: checkedOptionsNameList = [ buttonOptionsWidget._defaultCheckboxName ] buttonOptionsWidget.setCheckedCheckbox( buttonOptionsWidget._defaultCheckboxName) buttonOptionsWidget.enableAll() checkedOptionName = checkedOptionsNameList[0] orgClsNames = [ i for i in buttonOptionsWidget.get_checkboxs_name() if i in self._inserters_modelitems.keys() ] if (not orgClsNames): raise RuntimeError( "There are no or more than one inserters") inserterClassName = checkedOptionName if ((not self._scene._labeltool._enableAutoConnectLabelMode) and (self._scene._selectedDisplayItemsList is not None) and (len(self._scene._selectedDisplayItemsList) == 1)): parentModelItem = self._scene._selectedDisplayItemsList[0][ annotationscene. SELECTED_DISPLAYED_ITEMS_LIST_MODELITEM_INDEX] clsNameOfChild = inserterClassName if ((clsNameOfChild == config.ANNOTATION_PERSONBIKE_TOKEN) or (clsNameOfChild == config.ANNOTATION_PEDESTRAIN_TOKEN) or (clsNameOfChild == config.ANNOTATION_VEHICLE_TOKEN)): self._scene._selectedDisplayItemsList = [] parentModelItem = None elif (self._scene._sceneViewMode == config.OBJ_VIEW_MODE) and ( self._scene._objViewModeTopModelItem is not None): parentModelItem = self._scene._objViewModeTopModelItem else: parentModelItem = None LOG.info( "onClassButtonPressed ... self._scene._labeltool._enableAutoConnectLabelMode = {} parentModelItem = {}" .format(self._scene._labeltool._enableAutoConnectLabelMode, parentModelItem)) if not self._scene._labeltool._enableAutoConnectLabelMode: clsNameOfChild = inserterClassName isValid, rectBoundary = self._scene.checkModelItemValidity( clsNameOfChild, None, parentModelItem, self._scene._image_item, enablePopupMsgBox=True, enableEmitStatusMsg=False, enableCountingThisModelItem=True) if not isValid: LOG.info("enter hhhhhhhhhhhhhhh....") # -------------------------------------- # added by zx @ 2017-02-08 # to exit all inserters among all pannels # -------------------------------------- for i in self._scene._labeltool.propertyeditors(): if i: i.setCheckedAll(False) # self._scene._labeltool.exitInsertMode() self._scene.deselectAllItems() # -------------------------------------- return LOG.info("onClassButtonPressed ... call startInsertionMode...") self.startInsertionMode(pressedButtonName, inserterClassName) else: LOG.info("onClassButtonPressed ... call endInsertionMode...") self.endInsertionMode() return def startInsertionMode(self, pressedButtonName, inserterClassName): self.endInsertionMode(False) LOG.info( "Starting insertion mode for {} .. self._inserters_modelitems[{}]={} " .format(inserterClassName, inserterClassName, self._inserters_modelitems[inserterClassName])) for lc, buttonAndOption in self._widgets_dict.items(): buttonAndOption[0].setChecked(lc == pressedButtonName) if buttonAndOption[1]: # print ("startInsertionMode .. setchecked for {} option {} enabled = {} ".format(lc, buttonAndOption[1], (lc == pressedButtonName))) buttonAndOption[1].enableAll(lc == pressedButtonName) LOG.info( "startInsertionMode .. setchecked for {} button checked = {} ". format(lc, lc == inserterClassName)) # print ("startInsertionMode .. setchecked for {} button {} checked = {} ".format(lc, buttonAndOption[0], lc == inserterClassName)) self._current_toinsert_inserterClassName = inserterClassName # print "==== startInsertionMode set _current_is_insert_mode False ..." self._current_is_insert_mode = True LOG.info( u"startInsertionMode .. emit insertionModeStarted(pannel = {}, inserter = {})... " .format(self._idName, inserterClassName)) self.insertionModeStarted.emit(self._idName, inserterClassName, inserterClassName) def endInsertionMode(self, uncheck_buttons=True): if uncheck_buttons: self.setCheckedAll(False) LOG.info( u"endInsertionMode... PropertyEditor {} endInsertionMode(uncheck_buttons = {})" .format(self._displayName, uncheck_buttons)) # print (u"endInsertionMode... PropertyEditor {} endInsertionMode(uncheck_buttons = {})".format(self._displayName, uncheck_buttons)) self._current_is_insert_mode = False self.insertionModeEnded.emit() def enableAll(self, enabled=True): for v, buttonAndOption in self._widgets_dict.items(): buttonAndOption[0].setEnabled(enabled) def setCheckedAll(self, checked=True): for v, buttonAndOption in self._widgets_dict.items(): buttonAndOption[0].setChecked(checked) def getChecked(self): buttonname = None for buttonName, buttonWidgets in self._widgets_dict.iteritems(): if buttonWidgets[0].isChecked(): return buttonName return buttonname def setChecked(self, buttonName, checked=True): buttonWidget = self._widgets_dict.get(buttonName, None) if buttonWidget is not None: buttonWidget[0].setChecked(checked) def enable(self, buttonName, enabled=True): buttonWidget = self._widgets_dict.get(buttonName, None) if buttonWidget is not None: buttonWidget[0].setEnabled(enabled) def markEditButtons(self, buttonNamesList): for lc, buttonAndOption in self._widgets_dict.items(): # buttonAndOption[0].setFlat(lc not in buttonNamesList) buttonAndOption[0].setChecked(lc in buttonNamesList) def updateCurrentInserter(self, inserterClassName): self._current_toinsert_inserterClassName = inserterClassName return def isInsertingMode(self): return self._current_is_insert_mode def currentToInsertItemProperty(self): return self._inserters_modelitems.get( self._current_toinsert_inserterClassName, {}) if self._current_toinsert_inserterClassName else {} # return [inserter0ClassName, inserter1ClassName, ...] def getSupportedInserters(self): return self._inserters_modelitems.keys() def startEditMode(self, model_items): # If we're in insertion mode, ignore empty edit requests if self._current_is_insert_mode and len(model_items) == 0: return self.endInsertionMode() LOG.info("Starting edit mode for model_items: {} ".format(model_items)) self._current_toinsert_inserterClassName = None # print "==== startEditMode set _current_is_insert_mode False ..." self._current_is_insert_mode = False labelClasses = set([ item[config.METADATA_LABELCLASS_TOKEN] for item in model_items if config.METADATA_LABELCLASS_TOKEN in item ]) self.markEditButtons(labelClasses) def _setupGUI(self, _groupBoxName): self._widgets_dict = {} self._class_shortcuts = {} # Label class buttons qss = "QGroupBox::title {subcontrol-origin: margin; subcontrol-position: top left; padding: 0 3px; color : red; font-weight:bold; }" self._inserterButtonGroupbox = QGroupBox(_groupBoxName, self) self._inserterButtonGroupbox.setStyleSheet(qss) self._inserterButtonGroup_layout = FloatingLayout() self._inserterButtonGroupbox.setLayout( self._inserterButtonGroup_layout) # Global widget self._layout = MyVBoxLayout() self.setLayout(self._layout) self._layout.addWidget(self._inserterButtonGroupbox, 0) self._layout.addStretch(1) def onInserterButtonOptionChanged(self, _inserterButtonName, checkboxsInfo): # print "onInserterButtonOptionChanged {}: inserterButton {} checkboxinfo {}".format(self._idName, _inserterButtonName, checkboxsInfo) if not checkboxsInfo: return if len(checkboxsInfo) != 2: return inserterButtonName = str(_inserterButtonName) checkedWidgetsAttrDescDict = checkboxsInfo[0] allCheckboxsNameList = checkboxsInfo[1] if len(checkedWidgetsAttrDescDict) != 1: return checkedOptionName = checkedWidgetsAttrDescDict.keys()[0] if (self._current_toinsert_inserterClassName == checkedOptionName): return checkedOptionDisplayText = checkedWidgetsAttrDescDict.values()[0][ attrArea.checkedWidgetsAttrDescList_checkedWidgetText_idx] checkedOptionDisplayColor = checkedWidgetsAttrDescDict.values()[0][ attrArea.checkedWidgetsAttrDescList_checkedWidgetColor_idx] # change inserter button displaycolor # print "--- self._current_is_insert_mode = {} self._widgets_dict[{}][0].is_checked() = {} ...".format(self._current_is_insert_mode, inserterButtonName, self._widgets_dict[inserterButtonName][0].isChecked()) utils.set_qobj_stylesheet( self._widgets_dict[inserterButtonName][0], 'QPushButton', widgetBackgroundColor=None, widgetTextColor=None, widgetBackgroundColorWhenChecked=checkedOptionDisplayColor, widgetTextColorWhenChecked=None) if not self._current_is_insert_mode or self._scene._sceneViewMode == config.OBJ_VIEW_MODE: parentModelItem = None if self._scene._sceneViewMode == config.OBJ_VIEW_MODE: # print "_sceneViewMode = {} _objViewModeTopModelItem = {}".format(self._scene._sceneViewMode, self._scene._objViewModeTopModelItem) parentModelItem = self._scene._objViewModeTopModelItem if not parentModelItem: # get current scene's parent modelitem if len(self._scene._selectedDisplayItemsList) > 0: parentModelItem = self._scene._selectedDisplayItemsList[0][ annotationscene. SELECTED_DISPLAYED_ITEMS_LIST_MODELITEM_INDEX] # print "_selectedDisplayItemsList = {}".format(self._scene._selectedDisplayItemsList) if not parentModelItem: parentModelItem = self._scene._labeltool._current_image # print ("checkedOptionName = {} parentModelItem = {}".format(checkedOptionName, GET_ANNOTATION(parentModelItem))) # print ("allCheckboxsNameList = {}".format((allCheckboxsNameList))) # find all modelItems which has class which in is the option list of changed inserter option but not has not that class of option foundNum = 0 foundListList = [] for a in allCheckboxsNameList: foundList = model.findModelItemsWithSpecificClassNameFromRoot( a, parentModelItem, 5) # print "find {} => {}".format(a, foundList) foundNum += len(foundList) # if a != checkedOptionName else 0 maxNum = 1 if foundNum > maxNum: print "Error: there are {} items of {} in current image! We can only modify at least {} item once!".format( foundNum, allCheckboxsNameList, maxNum) foundListList = [] break if a != checkedOptionName: foundListList += foundList # print ("foundListList = {}".format((foundListList))) # update found modelitems' class field to current selected option if foundListList: for found in foundListList: if not found: continue modelItem = found[0] iterativeLevelNum = found[1] # print "ModelItem is changed from {} => {}!".format(modelItem.get_label_name(), checkedOptionName) modelItem.update({'class': checkedOptionName}, needEmitDatachanged=True) sceneItem = self._scene.modelItem_to_baseItem(modelItem) # print u"checkedOptionDisplayText = {} checkedOptionDisplayColor = {}".format(checkedOptionDisplayText, checkedOptionDisplayColor) sceneItem.updateInfo(checkedOptionDisplayText, checkedOptionDisplayColor) # newModelItem = copy.deepcopy(oldModelItem) # self._scene.deleteItems(self, [oldModelItem], recursiuve=True) else: # switch to new inserter as per current selected inserter button type # print "---------------- _current_is_insert_mode = {} ...".format(self._current_is_insert_mode) # print "call onInsertionModeStarted with {} {}...".format(checkedOptionName, inserterButtonName) self.updateCurrentInserter(checkedOptionName) self._scene.onInsertionModeStarted(self._idName, checkedOptionName, inserterButtonName) return def onInsertionModeStarted(self, _classNameToInsert, _buttonNameOfInserter): buttonNameOfInserter = str(_buttonNameOfInserter) self.setChecked(buttonNameOfInserter, True) self._current_is_insert_mode = True self.updateCurrentInserter(str(_classNameToInsert)) return
class AttrAreaWidget(QWidget): checkboxStateChangedSignal = pyqtSignal(str, object) def setAnnotationScene(self, annotationScene): self._scene = annotationScene def enableAllGroups(self, enabled=True): for gn, gw in self.checkboxGroupWidgets.items(): gw.setEnabled(enabled) gw.enableAll(enabled) def enableCheckboxGroup(self, checkboxGroupName, enabled=True): groupWidget = self.checkboxGroupWidgets.get(checkboxGroupName, None) if groupWidget is not None: groupWidget.setEnabled(enabled) groupWidget.enableAll(enabled) def enableCheckbox(self, checkboxGroupName, checkboxName, enabled=True): groupWidget = self.checkboxGroupWidgets.get(checkboxGroupName, None) if groupWidget is not None: groupWidget.enable(checkboxName, enabled) # return (names_list, texts_list, displaycolors_list) def get_group_config(self, checkboxGroupName): names = [] texts = [] displaycolors = [] groupWidget = self.checkboxGroupWidgets.get(checkboxGroupName, None) if groupWidget is not None: names, texts, displaycolors = groupWidget.get_config() return names, texts, displaycolors # return names_list def get_group_names(self): groupNames = [] for groupName in self.checkboxGroupWidgets.keys(): groupNames.append(groupName) return groupNames def setCheckedAllGroups(self, checked=True): for groupName, groupWidget in self.checkboxGroupWidgets.items(): groupWidget.setCheckedAll(checked) def setCheckedGroup(self, checkboxGroupName, checked=True): groupWidget = self.checkboxGroupWidgets.get(checkboxGroupName, None) if groupWidget is not None: groupWidget.setCheckedAll(checked) def setCheckedCheckbox(self, checkboxGroupName, checkboxName, checked=True): # print "checkboxGroupName {} checkboxName {} checked {} ...".format(checkboxGroupName, checkboxName, checked) groupWidget = self.checkboxGroupWidgets.get(checkboxGroupName, None) # print "checkboxGroupWidgets = {}...".format(self.checkboxGroupWidgets) if groupWidget is not None: # LOG.info("AttrAreaWidget.setCheckedCheckbox for group {} checked {} ..".format(checkboxGroupName, checked)) # print ("AttrAreaWidget.setCheckedCheckbox for group {} checked {} ..".format(checkboxGroupName, checked)) groupWidget.setCheckedCheckbox(checkboxName, checked) def setCheckedCheckboxs(self, checkboxGroupName, checkboxNamesList, checked=True): if checkboxNamesList is None: return groupWidget = self.checkboxGroupWidgets.get(checkboxGroupName, None) if groupWidget is not None: # LOG.info(u"{} AttrAreaWidget.setCheckedCheckbox for group {} box {} checked {} ..".format(self.groupName, checkboxGroupName, checkboxNamesList, checked)) groupWidget.setCheckedCheckboxs(checkboxNamesList, checked) def sendCheckedSignal(self, checkboxGroupName): groupWidget = self.checkboxGroupWidgets.get(checkboxGroupName, None) if groupWidget is not None: groupWidget.sendCheckedSignal() def getCheckedWidgetsOptionInfo(self, checkboxGroupName): groupWidget = self.checkboxGroupWidgets.get(checkboxGroupName, None) if groupWidget is not None: return groupWidget.getCheckedWidgetsOptionInfo() return None, None def setOptionStateChangedSignalSlot(self, checkboxStateChangedSignalSlot): if checkboxStateChangedSignalSlot is not None: # print u"pannel {}: checkboxStateChangedSignal{} checkboxStateChangedSignalSlot {} is connected...".format(self.idName, self.checkboxStateChangedSignal, checkboxStateChangedSignalSlot) self.checkboxStateChangedSignal.connect( checkboxStateChangedSignalSlot) def hideGroup(self, checkboxGroupName): groupWidget = self.checkboxGroupWidgets.get(checkboxGroupName, None) if groupWidget is not None: return groupWidget.hide() def __init__(self, property=None, idName=None, displayName=None, parent=None): QWidget.__init__(self, parent) self.hotkeys = [] self.displayName = displayName self.idName = idName self.vlayout = MyVBoxLayout() #QVBoxLayout() self.vlayout.setAlignment(Qt.AlignTop) self.vlayout.setSpacing(4) self.vlayout.setMargin(4) #self.vlayout.setContentsMargins(0, 0, 0, 44) # LOG.info("AttrAreaWidget constructor : property {} ...".format(property)) self.numGroups = len(property) if property is not None else 0 self.checkboxGroupsDescDict = {} self.checkboxGroupWidgets = {} for i in xrange(self.numGroups): thisGroupProperty = property[i] # thisGroupProperty is a dict thisGroupName = thisGroupProperty.get( 'name') # thisGroupName is a string thisGroupOption = thisGroupProperty.get( 'option' ) # thisGroupOption is a tuple of dicts. each dict describes a checkbox thisGroupText = thisGroupProperty.get('displaytext') isExclusive = False if thisGroupName in config.NON_EXCLUSIVE_ATTRS_TAG_LIST else True if thisGroupName == config.ANNOTATION_PERSONBIKE_TYPE_GROUP_TOKEN: checkboxWidgetMinWidthInPixels = 52 else: checkboxWidgetMinWidthInPixels = 38 if thisGroupName == config.ANNOTATION_UPPER_COLOR_TOKEN: thisGroup_maxCheckedNum = config.MAX_UPPER_COLOR_NUMBER thisGroup_maxSeperateWidgetNum = config.GUI_MAX_SEPERATE_UPPER_COLOR_WIDGET_NUMBER elif thisGroupName == config.ANNOTATION_LOWER_COLOR_TOKEN: thisGroup_maxCheckedNum = config.MAX_LOWER_COLOR_NUMBER thisGroup_maxSeperateWidgetNum = config.GUI_MAX_SEPERATE_LOWER_COLOR_WIDGET_NUMBER elif thisGroupName == config.ANNOTATION_VEHICLE_COLOR_TOKEN: thisGroup_maxCheckedNum = config.MAX_VEHICLE_COLOR_NUMBER thisGroup_maxSeperateWidgetNum = config.GUI_MAX_SEPERATE_VEHICLE_COLOR_WIDGET_NUMBER else: thisGroup_maxCheckedNum = config.MAX_CHECKED_OPTIONS_NUMBER thisGroup_maxSeperateWidgetNum = config.MAX_OPTIONS_NUMBER thisGroupWidget = CheckboxListWidget( thisGroupName, thisGroupText, isExclusive, thisGroupOption, self.checkboxStateChangedSignal, thisGroup_maxCheckedNum, thisGroup_maxSeperateWidgetNum) # add checkbox record to this checkbox group record thisGroupCheckboxs = {} for checkboxOption in thisGroupOption: thisCheckboxName = checkboxOption[ config.METADATA_ATTR_VALUE_TOKEN] thisCheckboxProperty = checkboxOption.copy() thisGroupCheckboxs[thisCheckboxName] = thisCheckboxProperty self.vlayout.addWidget(thisGroupWidget) self.checkboxGroupsDescDict[ thisGroupName] = thisGroupCheckboxs # add this checkbox group record to checkbox groups recrod self.checkboxGroupWidgets[thisGroupName] = thisGroupWidget # LOG.info("checkboxGroupWidgets = {} checkboxGroupsDescDict = {}".format(self.checkboxGroupWidgets, self.checkboxGroupsDescDict) self.vlayout.addStretch(1) self.setLayout(self.vlayout) return def stateHasChanged(self, checkedWidgetsAttrDescDict): # LOG.info("call AttrAreaWidget.stateHasChanged({})".format(checkedWidgetsAttrDescDict)) return def get_checked_widgets_name(self, group_name): widget = self.checkboxGroupWidgets.get(str(group_name), None) # LOG.info("AttrAreaWidget.get_checked_widgets_name ... widget = {}".format(widget)) checkedWidgetsNameList = widget.get_checked_widgets_name( ) if widget is not None else None # LOG.info("AttrAreaWidget.get_checked_widgets_name ... checkedWidget = {}".format(checkedWidget)) return checkedWidgetsNameList def add_hotkey(self, choice, name, hotkey): self.hotkeys.append((choice, name, hotkey)) def get_checked_widgets_attrDesc(self): descsDict = {} for widgetName, widgetInfo in self.checkboxWidgetsInfo.items(): if widgetInfo[0].isChecked(): desc = [None, None, None, None, None] desc[ checkedWidgetsAttrDescList_checkedWidget_idx] = widgetInfo[ 0] desc[ checkedWidgetsAttrDescList_checkedWidgetText_idx] = widgetInfo[ 1] desc[ checkedWidgetsAttrDescList_checkedWidgetColor_idx] = widgetInfo[ 2] desc[ checkedWidgetsAttrDescList_checkedWidgetStyleSheet_idx] = widgetInfo[ 3] descsDict[widgetName] = desc for widgetInfo in self.popupWidgetsInfo.values(): for actionWidget in widgetInfo[ popupWidgetsInfo_actionsWidgetList_idx]: if actionWidget.isChecked(): idx = widgetInfo[ popupWidgetsInfo_actionsWidgetList_idx].index( actionWidget) desc = [None, None, None, None, None] desc[ checkedWidgetsAttrDescList_checkedWidget_idx] = actionWidget desc[ checkedWidgetsAttrDescList_checkedWidgetText_idx] = widgetInfo[ popupWidgetsInfo_actionsTextList_idx][idx] desc[ checkedWidgetsAttrDescList_checkedWidgetColor_idx] = widgetInfo[ popupWidgetsInfo_actionsColorList_idx][idx] desc[ checkedWidgetsAttrDescList_checkedWidgetStyleSheet_idx] = widgetInfo[ popupWidgetsInfo_actionsWidgetStyleSheet_idx] desc[ checkedWidgetsAttrDescList_checkedWidgetPopupParentWidget_idx] = widgetInfo[ popupWidgetsInfo_pushButtonWidget_idx] widgetName = widgetInfo[ popupWidgetsInfo_actionsNameList_idx][idx] descsDict[widgetName] = desc return descsDict def startEditMode(self, model_items): return
class buttonWithOptionsWidget(QWidget): def __init__(self, annotation_scene, stateChangedSignalSlot=None, buttonWithOptionsProperty=None, displayName=None, parent=None): QWidget.__init__(self, parent) # print "buttonWithOptionsProperty = {}".format(comboPannelProperty) self.buttonWithOptionsProperty = buttonWithOptionsProperty self.name = displayName self.vlayout = QVBoxLayout() self.vlayout.setAlignment(Qt.AlignTop) self.vlayout.setSpacing(4) self.vlayout.setMargin(4) #self.vlayout.setContentsMargins(0, 0, 0, 44) self.vlayout.addWidget(self.propertyEditorWidget) self.vlayout.addWidget(self.attrAreaWidget) self.vlayout.addStretch(1) self.setLayout(self.vlayout) return def enableCheckbox(self, checkboxGroupName, checkboxName, enabled=True): groupWidget = self.checkboxGroupWidgets.get(checkboxGroupName, None) if groupWidget is not None: groupWidget.enable(checkboxName, enabled) def setCheckedCheckbox(self, checkboxName, checked=True): self.checkboxGroupWidget.setCheckedCheckbox(checkboxName, checked) def setCheckedCheckboxs(self, checkboxNamesList, checked=True): if checkboxNamesList is None: return groupWidget = self.checkboxGroupWidget.get(checkboxGroupName, None) if groupWidget is not None: # LOG.info(u"{} AttrAreaWidget.setCheckedCheckbox for group {} box {} checked {} ..".format(self.name, checkboxGroupName, checkboxNamesList, checked)) groupWidget.setCheckedCheckboxs(checkboxNamesList, checked) def sendCheckedSignal(self, checkboxGroupName): groupWidget = self.checkboxGroupWidgets.get(checkboxGroupName, None) if groupWidget is not None: groupWidget.sendCheckedSignal() def getCheckedWidgetsOptionInfo(self, checkboxGroupName): groupWidget = self.checkboxGroupWidgets.get(checkboxGroupName, None) if groupWidget is not None: return groupWidget.getCheckedWidgetsOptionInfo() return None, None def __init__(self, stateChangedSignalSlot=None, property=None, displayName=None, parent=None): QWidget.__init__(self, parent) self.hotkeys = [] self.name = displayName self.vlayout = MyVBoxLayout() #QVBoxLayout() self.vlayout.setAlignment(Qt.AlignTop) self.vlayout.setSpacing(4) self.vlayout.setMargin(4) #self.vlayout.setContentsMargins(0, 0, 0, 44) if stateChangedSignalSlot is not None: self.stateChanged.connect(stateChangedSignalSlot) # LOG.info("AttrAreaWidget constructor : property {} ...".format(property)) self.numGroups = len(property) if property is not None else 0 self.buttonGroupsDescDict = {} self.buttonGroupWidgets = {} for i in xrange(self.numGroups): thisGroupProperty = property[i] # thisGroupProperty is a dict thisGroupName = thisGroupProperty.get( 'name') # thisGroupName is a string thisGroupOption = thisGroupProperty.get( 'option' ) # thisGroupOption is a tuple of dicts. each dict describes a checkbox thisGroupText = thisGroupProperty.get('displaytext') thisGroup isExclusive = False if thisGroupName in config.NON_EXCLUSIVE_ATTRS_TAG_LIST else True if thisGroupName == config.ANNOTATION_PERSONBIKE_TYPE_GROUP_TOKEN: checkboxWidgetMinWidthInPixels = 52 else: checkboxWidgetMinWidthInPixels = 38 thisGroupWidget = checkBoxListWidget(thisGroupName, thisGroupText, isExclusive, thisGroupOption, self.stateChanged) if thisGroupName == config.ANNOTATION_UPPER_COLOR_TOKEN: thisGroupWidget.setMaxCheckedNum(config.MAX_UPPER_COLOR_NUMBER) thisGroupWidget.setMaxSeperateWidgetNum( config.GUI_MAX_SEPERATE_UPPER_COLOR_WIDGET_NUMBER) elif thisGroupName == config.ANNOTATION_LOWER_COLOR_TOKEN: thisGroupWidget.setMaxCheckedNum(config.MAX_LOWER_COLOR_NUMBER) thisGroupWidget.setMaxSeperateWidgetNum( config.GUI_MAX_SEPERATE_LOWER_COLOR_WIDGET_NUMBER) elif thisGroupName == config.ANNOTATION_VEHICLE_COLOR_TOKEN: thisGroupWidget.setMaxCheckedNum( config.MAX_VEHICLE_COLOR_NUMBER) thisGroupWidget.setMaxSeperateWidgetNum( config.GUI_MAX_SEPERATE_VEHICLE_COLOR_WIDGET_NUMBER) else: thisGroupWidget.setMaxCheckedNum( config.MAX_CHECKED_OPTIONS_NUMBER) thisGroupWidget.setMaxSeperateWidgetNum( config.MAX_OPTIONS_NUMBER) thisGroupCheckboxs = {} optCnt = 0 for checkboxOption in thisGroupOption: thisCheckboxName = checkboxOption[ config.METADATA_ATTR_VALUE_TOKEN] thisCheckboxText = checkboxOption[ config.METADATA_DISPLAYTEXT_TOKEN] thisCheckboxProperty = checkboxOption.copy() # get widget display color if thisGroupName == config.ANNOTATION_UPPER_COLOR_TOKEN or thisGroupName == config.ANNOTATION_LOWER_COLOR_TOKEN or thisGroupName == config.ANNOTATION_VEHICLE_COLOR_TOKEN: thisCheckboxBkgColorChecked = thisCheckboxProperty[ config.COLOR_ATTR_RGB_VALUE_TOKEN] thisCheckboxBkgColor = thisCheckboxBkgColorChecked else: thisCheckboxBkgColorChecked = thisCheckboxProperty[ config.METADATA_DISPLAYCOLOR_TOKEN] thisCheckboxBkgColor = None # calc widget text color # thisCheckboxBkgColorChecked string pattern: #123456 txtColorChecked = None if thisCheckboxBkgColorChecked is not None: import math rgba = utils.hexColorStrToRGBA(thisCheckboxBkgColorChecked) distance = math.sqrt((rgba[0] - 255)**2 + (rgba[1] - 255)**2 + (rgba[2] - 255)**2) txtColorChecked = '#ffffff' if distance > config.GUI_COLOR_TAG_TEXT_BLACKWHITE_TOGGLE_THRESHOLD else '#000000' txtColor = txtColorChecked if thisGroupName == config.ANNOTATION_UPPER_COLOR_TOKEN or thisGroupName == config.ANNOTATION_LOWER_COLOR_TOKEN or thisGroupName == config.ANNOTATION_VEHICLE_COLOR_TOKEN else None thisGroupCheckboxs[ thisCheckboxName] = thisCheckboxProperty # add checkbox record to this checkbox group record # add widget to this group if optCnt < thisGroupWidget._maxSeperateWidgetNum: thisGroupWidget.add_checkbox( thisCheckboxName, thisCheckboxText, thisCheckboxBkgColor, txtColor, thisCheckboxBkgColorChecked, txtColorChecked, checkboxWidgetMinWidthInPixels) else: thisGroupWidget.add_popup_button( config.GUI_MORE_WIDGET_DISPLAYTEXT, thisCheckboxName, thisCheckboxText, popupbutton_background_color="#808080", popupbutton_text_color="#ffffff", checkbox_background_color=thisCheckboxBkgColor, checkbox_text_color=txtColor) optCnt += 1 # thisGroupWidget.add_checkbox("Unset", u"Unset") thisGroupWidget.setLayout(thisGroupWidget.flayout) self.vlayout.addWidget(thisGroupWidget) self.checkboxGroupsDescDict[ thisGroupName] = thisGroupCheckboxs # add this checkbox group record to checkbox groups recrod self.checkboxGroupWidgets[thisGroupName] = thisGroupWidget # LOG.info("checkboxGroupWidgets = {} checkboxGroupsDescDict = {}".format(self.checkboxGroupWidgets, self.checkboxGroupsDescDict) self.vlayout.addStretch(1) self.setLayout(self.vlayout) return def stateHasChanged(self, checkedWidgetsAttrDescDict): # LOG.info("AttrAreaWidget.stateChanged with {}".format(checkedWidgetsAttrDescDict)) return def get_checked_widgets_name(self, group_name): widget = self.checkboxGroupWidgets.get(str(group_name), None) # LOG.info("AttrAreaWidget.get_checked_widgets_name ... widget = {}".format(widget)) checkedWidgetsNameList = widget.get_checked_widgets_name( ) if widget is not None else None # LOG.info("AttrAreaWidget.get_checked_widgets_name ... checkedWidget = {}".format(checkedWidget)) return checkedWidgetsNameList def add_hotkey(self, choice, name, hotkey): self.hotkeys.append((choice, name, hotkey)) def get_checked_widgets_attrDesc(self): descsDict = {} for widgetName, widgetInfo in self.checkboxWidgetsInfo.items(): if widgetInfo[0].isChecked(): desc = [None, None, None, None] desc[ checkedWidgetsAttrDescList_checkedWidget_idx] = widgetInfo[ 0] desc[ checkedWidgetsAttrDescList_checkedWidgetText_idx] = widgetInfo[ 1] desc[ checkedWidgetsAttrDescList_checkedWidgetStyleSheet_idx] = widgetInfo[ 2] descsDict[widgetName] = desc for widgetInfo in self.popupWidgetsInfo.values(): for actionWidget in widgetInfo[ popupWidgetsInfo_actionsWidgetList_idx]: if actionWidget.isChecked(): idx = widgetInfo[ popupWidgetsInfo_actionsWidgetList_idx].index( actionWidget) desc = [None, None, None, None] desc[ checkedWidgetsAttrDescList_checkedWidget_idx] = actionWidget desc[ checkedWidgetsAttrDescList_checkedWidgetText_idx] = widgetInfo[ popupWidgetsInfo_actionsTextList_idx][idx] desc[ checkedWidgetsAttrDescList_checkedWidgetStyleSheet_idx] = widgetInfo[ popupWidgetsInfo_actionsWidgetStyleSheet_idx] desc[ checkedWidgetsAttrDescList_checkedWidgetPopupParentWidget_idx] = widgetInfo[ popupWidgetsInfo_pushButtonWidget_idx] widgetName = widgetInfo[ popupWidgetsInfo_actionsNameList_idx][idx] descsDict[widgetName] = desc return descsDict def startEditMode(self, model_items): return