def deserialize(self, data, hashmap={}): res = super().deserialize(data, hashmap) try: combo = data['combo'] self.combo.setCurrentIndex(combo) return True & res except Exception as e: dumpException(e) return res
def deserialize(self, data, hashmap={}): res = super().deserialize(data, hashmap) try: value = data['value'] self.edit.setPlainText(value) return True & res except Exception as e: dumpException(e) return res
def deserialize(self, data, hashmap={}, restore_id=True, **kwargs): res = super().deserialize(data, hashmap) try: # self.value = pd.read_json(data['json_value']) # self.eval() return True & res except Exception as e: dumpException(e) return res
def remove(self, silent_for_socket: 'Socket' = None, silent=False): """ Safely remove this Edge. Removes `Graphics Edge` from the ``QGraphicsScene`` and it's reference to all GC to clean it up. Notifies nodes previously connected :class:`~nodeeditor.node_node.Node` (s) about this event. Triggers Nodes': - :py:meth:`~nodeeditor.node_node.Node.onEdgeConnectionChanged` - :py:meth:`~nodeeditor.node_node.Node.onInputChanged` :param silent_for_socket: :class:`~nodeeditor.node_socket.Socket` of a :class:`~nodeeditor.node_node.Node` which won't be notified, when this ``Edge`` is going to be removed :type silent_for_socket: :class:`~nodeeditor.node_socket.Socket` :param silent: ``True`` if no events should be triggered during removing :type silent: ``bool`` """ old_sockets = [self.start_socket, self.end_socket] # ugly hack, since I noticed that even when you remove grEdge from scene, # sometimes it stays there! How dare you Qt! if DEBUG: print(" - hide grEdge") self.grEdge.hide() if DEBUG: print(" - remove grEdge", self.grEdge) self.scene.grScene.removeItem(self.grEdge) self.scene.grScene.update() if DEBUG: print("# Removing Edge", self) if DEBUG: print(" - remove edge from all sockets") self.remove_from_sockets() if DEBUG: print(" - remove edge from scene") try: self.scene.removeEdge(self) except ValueError: pass if DEBUG: print(" - everything is done.") try: # notify nodes from old sockets for socket in old_sockets: if socket and socket.node: if silent: continue if silent_for_socket is not None and socket == silent_for_socket: # if we requested silence for Socket and it's this one, skip notifications continue # notify Socket's Node socket.node.onEdgeConnectionChanged(self) if socket.is_input: socket.node.onInputChanged(socket) except Exception as e: dumpException(e)
def loadFromFile(filename: str): with open(filename, "r") as file: raw_data = file.read() try: data = json.loads(raw_data) return data except json.JSONDecodeError: raise InvalidFile("%s is not a valid JSON file" % os.path.basename(filename)) except Exception as e: dumpException(e)
def deserialize(self, data, hashmap={}, restore_id=True, **kwargs): res = super().deserialize(data, hashmap) try: self.target_column = data['target_column'] self.factors = data['factors'] return True & res except Exception as e: dumpException(e) return res
def edgeDragStart(self, item:'QGraphicsItem'): """Code handling the start of dragging an `Edge` operation""" try: if DEBUG: print('View::edgeDragStart ~ Start dragging edge') if DEBUG: print('View::edgeDragStart ~ assign Start Socket to:', item.socket) self.drag_start_socket = item.socket self.drag_edge = self.getEdgeClass()(item.socket.node.scene, item.socket, None, EDGE_TYPE_BEZIER) self.drag_edge.grEdge.makeUnselectable() if DEBUG: print('View::edgeDragStart ~ dragEdge:', self.drag_edge) except Exception as e: dumpException(e)
def loadFromFile(self, filename): with open(filename, "r") as file: raw_data = file.read() try: data = json.loads(raw_data, encoding='utf-8') self.deserialize(data) self.has_been_modified = False except json.JSONDecodeError: raise InvalidFile("%s is not a valid JSON file" % os.path.basename(filename)) except Exception as e: dumpException(e)
def deserialize(self, data, hashmap={}): res = super().deserialize(data, hashmap) try: value = data['type'] self.expression.setText(value) value = data['name'] self.variable_name.setText(value) return True & res except Exception as e: dumpException(e) return res
def deserialize(self, data, hashmap={}, **kwargs): res = super().deserialize(data, hashmap) try: self.value = pd.read_json(data['json_value']) self.targetColumn.addItems(self.value.columns) fc = data['target_column'] #self.dropColumn.setCurrentIndex(self.value.columns.find_index(fc)) return True & res except Exception as e: dumpException(e) return res
def getInputSocket(self, index): try: edge = self.inputs[index].edges[0] socket = edge.getOtherSocket(self.inputs[index]) return socket except IndexError: print("EXC: Trying to get input, but none is attached to", self) return None except Exception as e: dumpException(e) return None
def deserialize(self, data, hashmap={}): res = super().deserialize(data, hashmap) try: value1 = data['value1'] value2 = data['value2'] self.conditional1.setText(value1) self.conditional2.setText(value2) return True & res except Exception as e: dumpException(e) return res
def getInput(self, index=0): try: edge = self.inputs[index].edges[0] socket = edge.getOtherSocket(self.inputs[index]) return socket.node except IndexError: logging.error( f"EXC: Trying to get input, but none is attached to {self}") return None except Exception as e: dumpException(e) return None
def leftMouseButtonRelease(self, event: QMouseEvent): """When Left mouse button was released""" # get item which we release mouse button on item = self.getItemAtClick(event) try: # logic if hasattr(item, "node") or isinstance( item, QDMGraphicsEdge) or item is None: if event.modifiers() & Qt.ShiftModifier: event.ignore() fakeEvent = QMouseEvent( event.type(), event.localPos(), event.screenPos(), Qt.LeftButton, Qt.NoButton, event.modifiers() | Qt.ControlModifier) super().mouseReleaseEvent(fakeEvent) return if self.mode == MODE_EDGE_DRAG: if self.distanceBetweenClickAndReleaseIsOff(event): res = self.dragging.edgeDragEnd(item) if res: return if self.mode == MODE_EDGE_CUT: self.cutIntersectingEdges() self.cutline.line_points = [] self.cutline.update() QApplication.setOverrideCursor(Qt.ArrowCursor) self.mode = MODE_NOOP return if self.rubberBandDraggingRectangle: self.rubberBandDraggingRectangle = False current_selected_items = self.grScene.selectedItems() if current_selected_items != self.grScene.scene._last_selected_items: if current_selected_items == []: self.grScene.itemsDeselected.emit() else: self.grScene.itemSelected.emit() self.grScene.scene._last_selected_items = current_selected_items return # otherwise deselect everything if item is None: self.grScene.itemsDeselected.emit() except: dumpException() super().mouseReleaseEvent(event)
def deserialize(self, data, hashmap={}): res = super().deserialize(data, hashmap) try: value = data['expression'] self.expression.setText(value) if data['usequotes']: self.usequotes.setChecked() if data['useangular']: self.useangular.setChecked() return True & res except Exception as e: dumpException(e) return res
def deserialize(self, data, hashmap={}): res = super().deserialize(data, hashmap) try: value = data['name'] self.macdriver_name_e.setText(value) self.macdriver_name = value value = data['description'] self.macdriver_description_e.setText(value) self.macdriver_description = value return True & res except Exception as e: dumpException(e) return res
def edgeDragStart(self, item): try: logging.debug('View::edgeDragStart ~ Start dragging edge') logging.debug( 'View::edgeDragStart ~ assign Start Socket to: {item.socket}' ) self.drag_start_socket = item.socket self.drag_edge = Edge(self.grScene.scene, item.socket, None, EDGE_TYPE_BEZIER) logging.debug( f'View::edgeDragStart ~ dragEdge: {self.drag_edge}') except Exception as e: dumpException(e)
def drawBackground(self, painter: QPainter, rect: QRect): """Draw background scene grid""" super().drawBackground(painter, rect) # here we create our grid left = int(math.floor(rect.left())) right = int(math.ceil(rect.right())) top = int(math.floor(rect.top())) bottom = int(math.ceil(rect.bottom())) first_left = left - (left % self.gridSize) first_top = top - (top % self.gridSize) # compute all lines to be drawn lines_light, lines_dark = [], [] for x in range(first_left, right, self.gridSize): if (x % (self.gridSize * self.gridSquares) != 0): lines_light.append(QLine(x, top, x, bottom)) else: lines_dark.append(QLine(x, top, x, bottom)) for y in range(first_top, bottom, self.gridSize): if (y % (self.gridSize * self.gridSquares) != 0): lines_light.append(QLine(left, y, right, y)) else: lines_dark.append(QLine(left, y, right, y)) # draw the lines painter.setPen(self._pen_light) painter.drawLines(*lines_light) painter.setPen(self._pen_dark) painter.drawLines(*lines_dark) #logoImg = QPixmap("icons\mercury.png") #painter.drawPixmap(QPoint(x-67, y-67), logoImg) if DEBUG_STATE: try: painter.setFont(self._font_state) painter.setPen(self._pen_state) painter.setRenderHint(QPainter.TextAntialiasing) offset = 14 rect_state = QRect(rect.x() + offset, rect.y() + offset, rect.width() - 2 * offset, rect.height() - 2 * offset) painter.drawText(rect_state, Qt.AlignRight | Qt.AlignTop, STATE_STRING[self.views()[0].mode].upper()) except: dumpException()
def edgeDragEnd(self, item: 'QGraphicsItem'): """Code handling the end of dragging an `Edge` operation. In this code return True if skip the rest of the mouse event processing :param item: Item in the `Graphics Scene` where we ended dragging an `Edge` :type item: ``QGraphicsItem`` """ self.mode = MODE_NOOP if DEBUG: print('View::edgeDragEnd ~ End dragging edge') self.drag_edge.remove( silent=True) # don't notify sockets about removing drag_edge self.drag_edge = None try: if isinstance(item, QDMGraphicsSocket): if item.socket != self.drag_start_socket: # if we released dragging on a socket (other then the beginning socket) # we wanna keep all the edges comming from target socket if not item.socket.is_multi_edges: item.socket.removeAllEdges() # we wanna keep all the edges comming from start socket if not self.drag_start_socket.is_multi_edges: self.drag_start_socket.removeAllEdges() ## Create new Edge new_edge = Edge(self.grScene.scene, self.drag_start_socket, item.socket, edge_type=EDGE_TYPE_BEZIER) if DEBUG: print("View::edgeDragEnd ~ created new edge:", new_edge, "connecting", new_edge.start_socket, "<-->", new_edge.end_socket) ## Send notifications for the new edge for socket in [self.drag_start_socket, item.socket]: # @TODO: Add possibility (ie when an input edge was replaced) to be silent and don't trigger change socket.node.onEdgeConnectionChanged(new_edge) if socket.is_input: socket.node.onInputChanged(socket) self.grScene.scene.history.storeHistory( "Created new edge by dragging", setModified=True) return True except Exception as e: dumpException(e) if DEBUG: print('View::edgeDragEnd ~ everything done.') return False
def deserialize(self, data, hashmap={}): res = super().deserialize(data, hashmap) try: value = data['value'] for i in range(len(value)): self.edit[i].setText(value[i]) if i < len(value) - 1: self.increaseWidgetSize() return True & res except Exception as e: dumpException(e) return res
def deserialize(self, data, hashmap={}): res = super().deserialize(data, hashmap) try: name = data['name'] scene = data['scene'] self.name.setText(name) tempScene = VplScene() tempScene.deserialize(scene) #self.innerScene.deserialize(scene) self.innerScene = tempScene #restore internal scene return True & res except Exception as e: dumpException(e) return res
def updateEditMenu(self): try: # print("update Edit Menu") active = self.getCurrentNodeEditorWidget() hasMdiChild = (active is not None) self.actPaste.setEnabled(hasMdiChild) self.actCut.setEnabled(hasMdiChild and active.hasSelectedItems()) self.actCopy.setEnabled(hasMdiChild and active.hasSelectedItems()) self.actDelete.setEnabled(hasMdiChild and active.hasSelectedItems()) self.actUndo.setEnabled(hasMdiChild and active.canUndo()) self.actRedo.setEnabled(hasMdiChild and active.canRedo()) except Exception as e: dumpException(e)
def eval(self, param={}): if not self.isDirty() and not self.isInvalid(): print(" _> returning cached %s value:" % self.__class__.__name__, self.value) return self.value try: val = self.evalImplementation(param) return val except ValueError as e: self.markInvalid() self.grNode.setToolTip(str(e)) self.markDescendantsDirty() except Exception as e: self.markInvalid() self.grNode.setToolTip(str(e)) dumpException(e)
def deserialize(self, data, hashmap={}, restore_id=True): try: if restore_id: self.id = data['id'] hashmap[data['id']] = self self.setPos(data['pos_x'], data['pos_y']) self.title = data['title'] data['inputs'].sort(key=lambda socket: socket['index'] + socket[ 'position'] * 10000) data['outputs'].sort(key=lambda socket: socket['index'] + socket[ 'position'] * 10000) num_inputs = len(data['inputs']) num_outputs = len(data['outputs']) self.inputs = [] for socket_data in data['inputs']: new_socket = Socket(node=self, index=socket_data['index'], position=socket_data['position'], socket_type=socket_data['socket_type'], count_on_this_node_side=num_inputs, is_input=True) new_socket.deserialize(socket_data, hashmap, restore_id) self.inputs.append(new_socket) self.outputs = [] for socket_data in data['outputs']: new_socket = Socket(node=self, index=socket_data['index'], position=socket_data['position'], socket_type=socket_data['socket_type'], count_on_this_node_side=num_outputs, is_input=False) new_socket.deserialize(socket_data, hashmap, restore_id) self.outputs.append(new_socket) except Exception as e: dumpException(e) # also deseralize the content of the node res = self.content.deserialize(data['content'], hashmap) #logging.debug(f'Node {self.__class__.__name__} has {len(self.inputs)} inputs and {len(self.outputs)} outputs') return True & res
def contextMenuEvent(self, event): try: item = self.scene.getItemAt(event.pos()) if DEBUG_CONTEXT: print(item) if type(item) == QGraphicsProxyWidget: item = item.widget() if hasattr(item, 'node') or hasattr(item, 'socket'): self.handleNodeContextMenu(event) elif hasattr(item, 'edge'): self.handleEdgeContextMenu(event) else: self.handleNewNodeContextMenu(event) return super().contextMenuEvent(event) except Exception as e: dumpException(e)
def getInput(self, index:int=0) -> ['Node', None]: """ Get the **first** `Node` connected to the Input specified by `index` :param index: Order number of the `Input Socket` :type index: ``int`` :return: :class:`~nodeeditor.node_node.Node` which is connected to the specified `Input` or ``None`` if there is no connection of index is out of range :rtype: :class:`~nodeeditor.node_node.Node` or ``None`` """ try: input_socket = self.inputs[index] if len(input_socket.edges) == 0: return None connecting_edge = input_socket.edges[0] other_socket = connecting_edge.getOtherSocket(self.inputs[index]) return other_socket.node except Exception as e: dumpException(e) return None
def getInput(self, index:int=0) -> 'Node': """ Get the **first** `Node` connected to the Input specified by `index` :param index: Order number of the `Input Socket` :type index: ``int`` :return: :class:`~nodeeditor.node_node.Node` which is connected to the specified `Input` or ``None`` if there is no connection of index is out of range :rtype: :class:`~nodeeditor.node_node.Node` """ try: edge = self.inputs[index].edges[0] socket = edge.getOtherSocket(self.inputs[index]) return socket.node except IndexError: print("EXC: Trying to get input, but none is attached to", self) return None except Exception as e: dumpException(e) return None
def deserialize(self, data, hashmap={}): res = super().deserialize(data, hashmap) try: value = data['value'] # Set the text to the values that were saved for i in range(len(value)): self.edit[i].setText(value[i]) # Increase the number of combo boxes based on the number of if/elses if i < len(value) - 1: self.increaseWidgetSize() return True & res except Exception as e: dumpException(e) return res
def edgeDragEnd(self, item): """ return True if skip the rest of the code """ self.mode = MODE_NOOP logging.debug('View::edgeDragEnd ~ End dragging edge') self.drag_edge.remove() self.drag_edge = None try: if type(item) is QDMGraphicsSocket: if item.socket != self.drag_start_socket: # if we released dragging on a socket (other then the beginning socket) # we wanna keep all the edges comming from target socket if not item.socket.is_multi_edges: item.socket.removeAllEdges() # we wanna keep all the edges comming from start socket if not self.drag_start_socket.is_multi_edges: self.drag_start_socket.removeAllEdges() new_edge = Edge(self.grScene.scene, self.drag_start_socket, item.socket, edge_type=EDGE_TYPE_BEZIER) logging.debug( f"View::edgeDragEnd ~ created new edge: {new_edge}, " f"connecting {new_edge.start_socket} <--> {new_edge.end_socket}" ) for socket in [self.drag_start_socket, item.socket]: socket.node.onEdgeConnectionChanged(new_edge) if socket.is_input: socket.node.onInputChanged(new_edge) self.grScene.scene.history.storeHistory( "Created new edge by dragging", setModified=True) return True except Exception as e: dumpException(e) logging.debug('View::edgeDragEnd ~ everything done.') return False
def getInputWithSocket(self, index: int=0) -> [('Node', 'Socket'), (None, None)]: """ Get the **first** `Node` connected to the Input specified by `index` and the connection `Socket` :param index: Order number of the `Input Socket` :type index: ``int`` :return: Tuple containing :class:`~nodeeditor.node_node.Node` and :class:`~nodeeditor.node_socket.Socket` which is connected to the specified `Input` or ``None`` if there is no connection or the index is out of range :rtype: (:class:`~nodeeditor.node_node.Node`, :class:`~nodeeditor.node_socket.Socket`) """ try: input_socket = self.inputs[index] if len(input_socket.edges) == 0: return None, None connecting_edge = input_socket.edges[0] other_socket = connecting_edge.getOtherSocket(self.inputs[index]) return other_socket.node, other_socket except Exception as e: dumpException(e) return None, None