def postCreate(self, jsonTemplate=None): super(pythonNode, self).postCreate(jsonTemplate) if jsonTemplate is None: return if 'nodeData' in jsonTemplate: self.nodeData = jsonTemplate['nodeData'] for inpJson in jsonTemplate['inputs']: pin = self.getPinByName(inpJson["name"]) if not pin: pin = self.createInputPin( pinName=inpJson["name"], dataType=inpJson["dataType"], defaultValue=getPinDefaultValueByType(inpJson["dataType"]), foo=self.compute) pin.deserialize(inpJson) for outJson in jsonTemplate['outputs']: pin = self.getPinByName(outJson["name"]) if not pin: pin = self.createOutputPin( pinName=inpJson["name"], dataType=inpJson["dataType"], defaultValue=getPinDefaultValueByType(inpJson["dataType"])) pin.deserialize(outJson) self.autoAffectPins()
def createVariable(self, dataType=str('AnyPin'), accessLevel=AccessLevel.public, uid=None, name=str("var")): """Creates variable inside this graph scope :param dataType: Variable data type :type dataType: str :param accessLevel: Variable access level :type accessLevel: :class:`~PyFlow.Core.Common.AccessLevel` :param uid: Variable unique identifier :type uid: :class:`uuid.UUID` :param name: Variable name :type name: str """ name = self.graphManager.getUniqVariableName(name) var = Variable(self, getPinDefaultValueByType(dataType), name, dataType, accessLevel=accessLevel, uid=uid) self._vars[var.uid] = var return var
def dataType(self, value): assert (isinstance(value, str)) if value != self._dataType: self._dataType = value self.updatePackageName() self.value = getPinDefaultValueByType(self._dataType) self.dataTypeChanged.send(value)
def createPropertiesWidget(self, propertiesWidget): baseCategory = CollapsibleFormWidget(headName="Base", modify=True) # name le_name = QLineEdit(self._rawVariable.name) le_name.returnPressed.connect(lambda: self.setName(le_name.text())) baseCategory.addWidget("Name", le_name) # data type cbTypes = EnumComboBox([ pin.__name__ for pin in getAllPinClasses() if pin.IsValuePin() if pin.__name__ != "AnyPin" ]) cbTypes.setCurrentIndex(cbTypes.findText(self.dataType)) cbTypes.setEditable(False) cbTypes.changeCallback.connect(self.setDataType) propertiesWidget.addWidget(baseCategory) # structure type cbStructure = EnumComboBox( [i.name for i in (PinStructure.Single, PinStructure.Array)]) cbStructure.setEditable(False) cbStructure.setCurrentIndex( cbStructure.findText(self._rawVariable.structure.name)) cbStructure.changeCallback.connect(self.onStructureChanged) propertiesWidget.addWidget(baseCategory) baseCategory.addWidget("Type", cbTypes) baseCategory.addWidget("Structure", cbStructure) valueCategory = CollapsibleFormWidget(headName="Value") # current value if self._rawVariable.structure == PinStructure.Single: if not type(self._rawVariable.value) in {list, set, dict, tuple}: def valSetter(x): self._rawVariable.value = x w = createInputWidget( self._rawVariable.dataType, valSetter, getPinDefaultValueByType(self._rawVariable.dataType)) if w: w.setWidgetValue(self._rawVariable.value) w.setObjectName(self._rawVariable.name) valueCategory.addWidget(self._rawVariable.name, w) # access level cb = QComboBox() cb.addItem('public', 0) cb.addItem('private', 1) cb.addItem('protected', 2) def accessLevelChanged(x): self._rawVariable.accessLevel = AccessLevel[x] EditorHistory().saveState("Change variable access level", modify=True) cb.currentTextChanged.connect(accessLevelChanged) cb.setCurrentIndex(self._rawVariable.accessLevel) valueCategory.addWidget('Access level', cb) propertiesWidget.addWidget(valueCategory)
def setType(self, dataType): if not self.changeTypeOnConnection: return False if self.activeDataType != self.__class__.__name__ and self.singleInit: # Marked as single init. Type already been set. Skip return False otherClass = findPinClassByType(dataType) self.super = otherClass self.activeDataType = dataType if not self.isArray(): self._data = getPinDefaultValueByType(self.activeDataType) else: self._data = [] self.setDefaultValue(self._data) self.color = otherClass.color self.dirty = True self.jsonEncoderClass = otherClass.jsonEncoderClass self.jsonDecoderClass = otherClass.jsonDecoderClass self.supportedDataTypes = otherClass.supportedDataTypes self._supportedDataTypes = otherClass.supportedDataTypes() self.typeChanged.send(self.activeDataType) self._free = self.activeDataType == self.__class__.__name__ return True
def createOutputPin(self, pinName, dataType, defaultValue=None, structure=PinStructure.Single, constraint=None, structConstraint=None, supportedPinDataTypes=[], group=""): """Creates output pin :param pinName: Pin name :type pinName: str :param dataType: Pin data type :type dataType: str :param defaultValue: Pin default value :type defaultValue: object :param structure: Pin structure :type structure: :class:`~PyFlow.Core.Common.PinStructure.Single` :param constraint: Pin constraint. Should be any hashable type. We use str :type constraint: object :param structConstraint: Pin struct constraint. Also should be hashable type :type structConstraint: object :param supportedPinDataTypes: List of allowed pin data types to be connected. Used by AnyPin :type supportedPinDataTypes: list(str) :param group: Pin group. Used only by ui wrapper :type group: str """ pinName = self.getUniqPinName(pinName) p = CreateRawPin(pinName, self, dataType, PinDirection.Output) p.structureType = structure p.group = group if structure == PinStructure.Array: p.initAsArray(True) elif structure == PinStructure.Dict: p.initAsDict(True) elif structure == PinStructure.Multi: p.enableOptions(PinOptions.ArraySupported) if defaultValue is not None or dataType == "AnyPin": p.setDefaultValue(defaultValue) p.setData(defaultValue) if dataType == "AnyPin": p.setTypeFromData(defaultValue) else: p.setDefaultValue(getPinDefaultValueByType(dataType)) if dataType == "AnyPin" and supportedPinDataTypes: def supportedDataTypes(): return supportedPinDataTypes p.supportedDataTypes = supportedDataTypes if constraint is not None: p.updateConstraint(constraint) if structConstraint is not None: p.updateStructConstraint(structConstraint) return p
def applyData(self): # reset node # TODO: do not remove pins if data is the same self.resetNode() node = self.graph.nodes[self.nodeUid] # label lbText = self.leLabel.text() if not lbText == '': node.label().setPlainText(lbText) # assign compute method code = self.plainTextEdit.toPlainText() # Py3FunctionCompiler works for python 2 as well foo = Py3FunctionCompiler('compute').compile(code) node.compute = MethodType(foo, node) node.currentComputeCode = code for index in range(self.lwOutputs.count()): w = self.lwOutputs.itemWidget(self.lwOutputs.item(index)) if isinstance(w, WPinWidget): dataType = w.dataType() rawPin = node._rawNode.createOutputPin( w.name(), w.dataType(), getPinDefaultValueByType(dataType)) uiPin = node._createUIPinWrapper(rawPin) w.lePinName.setText(uiPin.name) uiPin.getLabel()().setVisible(not w.shouldHideLabel()) # recreate pins from editor data for index in range(self.lwInputs.count()): w = self.lwInputs.itemWidget(self.lwInputs.item(index)) if isinstance(w, WPinWidget): dataType = w.dataType() compute = node.compute if dataType == "ExecPin" else None rawPin = node._rawNode.createInputPin( w.name(), w.dataType(), getPinDefaultValueByType(dataType), compute) uiPin = node._createUIPinWrapper(rawPin) w.lePinName.setText(uiPin.name) uiPin.getLabel()().setVisible(not w.shouldHideLabel()) node.autoAffectPins() # reset node shape node.updateNodeShape()
def deserialize(graph, jsonData, *args, **kwargs): name = jsonData['name'] dataType = jsonData['dataType'] if dataType != "AnyPin": pinClass = findPinClassByType(dataType) value = json.loads(jsonData['value'], cls=pinClass.jsonDecoderClass()) else: value = getPinDefaultValueByType("AnyPin") accessLevel = AccessLevel(jsonData['accessLevel']) uid = uuid.UUID(jsonData['uuid']) return Variable(graph, value, name, dataType, accessLevel, uid)
def createVariable(self, dataType=str('AnyPin'), accessLevel=AccessLevel.public, uid=None, name=str("var")): name = self.graphManager.getUniqVariableName(name) var = Variable(self, getPinDefaultValueByType(dataType), name, dataType, accessLevel=accessLevel, uid=uid) self.vars[var.uid] = var return var
def deserialize(data, graph): pinClass = findPinClassByType(data['dataType']) varUid = uuid.UUID(data['uuid']) var = graph.getApp().variablesWidget.createVariable( dataType=data['dataType'], accessLevel=AccessLevel(data['accessLevel']), uid=varUid) var.setName(data['name']) var.setDataType(data['dataType']) if data['dataType'] == 'AnyPin': var.value = getPinDefaultValueByType('AnyPin') else: var.value = json.loads(data['value'], cls=pinClass.jsonDecoderClass()) return var
def createInputPin(self, pinName, dataType, defaultValue=None, foo=None, structure=PinStructure.Single, constraint=None, structConstraint=None, allowedPins=[], group=""): # check unique name pinName = self.getUniqPinName(pinName) p = CreateRawPin(pinName, self, dataType, PinDirection.Input) p.structureType = structure p.group = group if structure == PinStructure.Array: p.initAsArray(True) elif structure == PinStructure.Dict: p.initAsDict(True) elif structure == PinStructure.Multi: p.enableOptions(PinOptions.ArraySupported) if foo: p.onExecute.connect(foo, weak=False) if defaultValue is not None or dataType == "AnyPin": p.setDefaultValue(defaultValue) p.setData(defaultValue) if dataType == "AnyPin": p.setTypeFromData(defaultValue) else: p.setDefaultValue(getPinDefaultValueByType(dataType)) if dataType == "AnyPin" and allowedPins: def supportedDataTypes(): return allowedPins p._supportedDataTypes = p._defaultSupportedDataTypes = tuple( allowedPins) p.supportedDataTypes = supportedDataTypes if constraint is not None: p.updateConstraint(constraint) if structConstraint is not None: p.updatestructConstraint(structConstraint) return p
def setType(self, dataType): """Here is where :py:class:`AnyPin` heredates all the properties from other defined dataTypes and act like those :param dataType: New DataType :type dataType: string :returns: True if succes setting dataType :rtype: {bool} """ if self.activeDataType == dataType: return True if not self.optionEnabled(PinOptions.ChangeTypeOnConnection): return False if self.activeDataType != self.__class__.__name__ and self.singleInit: # Marked as single init. Type already been set. Skip return False otherClass = findPinClassByType(dataType) if dataType != "AnyPin": self.super = otherClass else: self.super = None if self.activeDataType == "AnyPin" and self._lastError2 == None: self.prevDataType = "AnyPin" else: self.prevDataType = None self.activeDataType = dataType if not self.isArray(): self.setData(getPinDefaultValueByType(self.activeDataType)) else: self.setData([]) self.setDefaultValue(self._data) self.color = otherClass.color self.dirty = True self.jsonEncoderClass = otherClass.jsonEncoderClass self.jsonDecoderClass = otherClass.jsonDecoderClass self.supportedDataTypes = otherClass.supportedDataTypes self._supportedDataTypes = otherClass.supportedDataTypes() self.typeChanged.send(self.activeDataType) self.dataBeenSet.send(self) return True
def createPropertiesWidget(self, propertiesWidget): baseCategory = CollapsibleFormWidget(headName="Base") # name le_name = QLineEdit(self._rawVariable.name) le_name.returnPressed.connect(lambda: self.setName(le_name.text())) baseCategory.addWidget("Name", le_name) # data type cbTypes = VarTypeComboBox(self) baseCategory.addWidget("Type", cbTypes) propertiesWidget.addWidget(baseCategory) valueCategory = CollapsibleFormWidget(headName="Value") # current value def valSetter(x): self._rawVariable.value = x w = createInputWidget( self._rawVariable.dataType, valSetter, getPinDefaultValueByType(self._rawVariable.dataType)) if w: w.setWidgetValue(self._rawVariable.value) w.setObjectName(self._rawVariable.name) valueCategory.addWidget(self._rawVariable.name, w) # access level cb = QComboBox() cb.addItem('public', 0) cb.addItem('private', 1) cb.addItem('protected', 2) def accessLevelChanged(x): self._rawVariable.accessLevel = AccessLevel[x] cb.currentTextChanged.connect(accessLevelChanged) cb.setCurrentIndex(self._rawVariable.accessLevel) valueCategory.addWidget('Access level', cb) propertiesWidget.addWidget(valueCategory)
def deserialize(graph, jsonData, *args, **kwargs): name = jsonData['name'] dataType = "BoolPin" if jsonData["structure"] == StructureType.Dict.name: keyDataType = jsonData['dictKeyType'] valueDataType = jsonData['dictValueType'] value = PFDict(keyDataType, valueDataType) else: dataType = jsonData['dataType'] if dataType != "AnyPin": pinClass = findPinClassByType(dataType) value = json.loads(jsonData['value'], cls=pinClass.jsonDecoderClass()) else: value = getPinDefaultValueByType("AnyPin") accessLevel = AccessLevel[jsonData['accessLevel']] structure = StructureType[jsonData['structure']] uid = uuid.UUID(jsonData['uuid']) return Variable(graph, value, name, dataType, accessLevel, structure, uid)
def createOutputPin(self, pinName, dataType, defaultValue=None, structure=PinStructure.Single, constraint=None, structConstraint=None, allowedPins=[], group=""): pinName = self.getUniqPinName(pinName) p = CreateRawPin(pinName, self, dataType, PinDirection.Output) p.structureType = structure p.group = group if structure == PinStructure.Array: p.initAsArray(True) elif structure == PinStructure.Multi: p.enableOptions(PinOptions.ArraySupported) if defaultValue is not None: p.setDefaultValue(defaultValue) p.setData(defaultValue) else: p.setDefaultValue(getPinDefaultValueByType(dataType)) if dataType == "AnyPin" and allowedPins: def supportedDataTypes(): return allowedPins p.supportedDataTypes = supportedDataTypes if constraint is not None: p.updateConstraint(constraint) if structConstraint is not None: p.updatestructConstraint(structConstraint) return p
def createInputPin(self, pinName, dataType, defaultValue=None, foo=None, structure=StructureType.Single, constraint=None, structConstraint=None, supportedPinDataTypes=[], group=""): """Creates input pin :param pinName: Pin name :type pinName: str :param dataType: Pin data type :type dataType: str :param defaultValue: Pin default value :type defaultValue: object :param foo: Pin callback. used for exec pins :type foo: function :param structure: Pin structure :type structure: :class:`~PyFlow.Core.Common.StructureType.Single` :param constraint: Pin constraint. Should be any hashable type. We use str :type constraint: object :param structConstraint: Pin struct constraint. Also should be hashable type :type structConstraint: object :param supportedPinDataTypes: List of allowed pin data types to be connected. Used by AnyPin :type supportedPinDataTypes: list(str) :param group: Pin group. Used only by ui wrapper :type group: str """ pinName = self.getUniqPinName(pinName) p = CreateRawPin(pinName, self, dataType, PinDirection.Input) p.structureType = structure p.group = group if structure == StructureType.Array: p.initAsArray(True) elif structure == StructureType.Dict: p.initAsDict(True) elif structure == StructureType.Multi: p.enableOptions(PinOptions.ArraySupported) if foo: p.onExecute.connect(foo, weak=False) if defaultValue is not None or dataType == "AnyPin": p.setDefaultValue(defaultValue) p.setData(defaultValue) if dataType == "AnyPin": p.setTypeFromData(defaultValue) else: p.setDefaultValue(getPinDefaultValueByType(dataType)) if dataType == "AnyPin" and supportedPinDataTypes: def supportedDataTypes(): return supportedPinDataTypes p._supportedDataTypes = p._defaultSupportedDataTypes = tuple( supportedPinDataTypes) p.supportedDataTypes = supportedDataTypes if constraint is not None: p.updateConstraint(constraint) if structConstraint is not None: p.updateStructConstraint(structConstraint) p.dataBeenSet.connect(self.setDirty.send) p.markedAsDirty.connect(self.setDirty.send) return p