def __init__(self, parent=None): QObject.__init__(self, parent) self._nodeViews = {} self._linkViews = [] self._scene = NodeScene(self) # !TODO: Temporary self._scene.setSceneRect(-200, -200, 1000, 600) # !TODO: Move to some initialize method self._view = NodeEditorView() self._view.setScene(self._scene) self._view.setGeometry(100, 50, 1200, 800) self._view.contextMenu.connect(self.contextMenu) self._view.show() self._addNodesActions = [] for item in enumerate(self._registeredNodeTypes): a = QAction(item[1], self) a.setData(item[0]) self._addNodesActions.append(a)
def __init__(self, parent=None): QObject.__init__(self, parent) self._nodeViews = {} self._linkViews = [] self._scene = NodeScene(self) # !TODO: Temporary self._scene.setSceneRect(-200,-200,1000,600) # !TODO: Move to some initialize method self._view = NodeEditorView() self._view.setScene(self._scene) self._view.setGeometry(100, 50, 1200, 800) self._view.contextMenu.connect(self.contextMenu) self._view.show() self._addNodesActions = [] for item in enumerate(self._registeredNodeTypes): a = QAction(item[1], self) a.setData(item[0]) self._addNodesActions.append(a)
class NodeController(QObject): # These ones goes to model _registeredNodeTypes = ['Image from disk', 'Gaussian blur', \ 'Preview window', 'Grayscale', 'Mixture of Gaussians'] _nodeId = 0 def __init__(self, parent=None): QObject.__init__(self, parent) self._nodeViews = {} self._linkViews = [] self._scene = NodeScene(self) # !TODO: Temporary self._scene.setSceneRect(-200,-200,1000,600) # !TODO: Move to some initialize method self._view = NodeEditorView() self._view.setScene(self._scene) self._view.setGeometry(100, 50, 1200, 800) self._view.contextMenu.connect(self.contextMenu) self._view.show() self._addNodesActions = [] for item in enumerate(self._registeredNodeTypes): a = QAction(item[1], self) a.setData(item[0]) self._addNodesActions.append(a) ''' Zwraca widok wezla o podanym kluczu ID ''' def nodeView(self, key): return self._nodeViews[key] ''' Dodaje nowy widok wezla ''' def addNodeView(self, key, title): node = NodeView(title) node.setData(NodeDataIndex.NodeKey, key) #node.installEventFilter(self.nodeManager) self._nodeViews[key] = node self._scene.addItem(node) return node ''' Usuwa widok wezla o podanym kluczu ID ''' def deleteNodeView(self, key): print 'deleting node with key:', key # if key in self._nodeViews: # print 'deleting node with key: {0}'.format(key) # nodeView = self._nodeViews.pop(key) # # !TODO: Nie pamietam juz czy logika sie tym zajmie czy nie # # - chodzi o usuniecie wiszacych polaczen # lvs = filter(lambda lv: lv.connecting(nodeView), self._linkViews) # for link in lvs: # link.dtor() # self._linkViews.remove(link) # self._scene.removeItem(nodeView) # return True # else: # print 'node with key: {0} not found'.format(key) # return False ''' Zwraca liste polaczen wchodzacych do danego wezla ''' def inputLinkViews(self, nodeKey): if nodeKey in self._nodeViews: nv = self._nodeViews[nodeKey] return filter(lambda lv: lv.inputConnecting(nv), self._linkViews) return None ''' Zwraca liste polaczen wychodzacych z danego wezla ''' def outputLinkViews(self, nodeKey): if nodeKey in self._nodeViews: nv = self._nodeViews[nodeKey] return filter(lambda lv: lv.outputConnecting(nv), self._linkViews) return None ''' Tworzy nowe (wizualne) polaczenie miedzy danymi gniazdami ''' def linkNodeViews(self, fromSocketView, toSocketView): # TODO!: To bedzie w logice # Check if we aren't trying to create already existing connection for linkView in self._linkViews: if linkView.connects(fromSocketView, toSocketView): QMessageBox.critical(None, 'NodeView', 'Connection already exists') return link = NodeLinkView(fromSocketView, toSocketView, None) link.setDrawDebug(DEBUG_LINKS) fromSocketView.addLink(link) toSocketView.addLink(link) self._linkViews.append(link) #link.installEventFilter(self.nodeManager) self._scene.addItem(link) ''' Usuwa polaczenie (wizualne) miedzy danymi gniazdami ''' def unlinkNodeViews2(self, fromSocketView, toSocketView): for linkView in self._linkViews: if linkView.connects(fromSocketView, toSocketView): self._scene.removeItem(linkView) self._linkViews.remove(linkView) return True return False def unlinkNodeViews(self, linkView): pass # Normalnie, za to odpowiedzialna jest logika def _addNode(self, nodeTypeId, scenePos): if nodeTypeId < len(self._registeredNodeTypes): title = self._registeredNodeTypes[nodeTypeId] nodeId = self._nodeId node = self.addNodeView(nodeId, title) node.setPos(scenePos) if title == 'Image from disk': node.addSocketView(0, 'Output', True) elif title == 'Gaussian blur': node.addSocketView(0, 'Input') node.addSocketView(1, 'Sigma') node.addSocketView(0, 'Output', True) elif title == 'Preview window': node.addSocketView(0, 'Input') elif title == 'Grayscale': node.addSocketView(0, 'Input') node.addSocketView(0, 'Output', True) elif title == 'Mixture of Gaussians': node.addSocketView(0, 'Frame') node.addSocketView(0, 'Foreground mask', True) self._nodeId += 1 ''' Reakcja na opuszczenie nowego polaczenia ''' @Slot(NodeSocketView, NodeSocketView) def draggingLinkDropped(self, fromSocketView, toSocketView): self.linkNodeViews(fromSocketView, toSocketView) @Slot(NodeSocketView) def draggingLinkStarted(self, fromSocketView): self._scene.dragging = True #print 'dragging started from', fromSocketView @Slot(NodeSocketView) def draggingLinkStopped(self, fromSocketView): self._scene.dragging = False #print 'dragging stopped' ''' Reakcja na probe pokazania menu kontekstowego pochodzacego z widoku sceny ''' @Slot(QPoint, QPointF) def contextMenu(self, globalPos, scenePos): items = self._scene.items(scenePos, Qt.ContainsItemShape, Qt.AscendingOrder) # If we clicked onto empty space if not items: menu = QMenu() menuAddNode = menu.addMenu('Add node') for a in self._addNodesActions: menuAddNode.addAction(a) ret = menu.exec_(globalPos) if ret is not None: self._addNode(ret.data(), scenePos) else: for item in items: if item.type() == NodeView.Type: menu = QMenu() action = QAction('Delete node', None) action.setData(10) menu.addAction(action) ret = menu.exec_(globalPos) if ret is not None and isinstance(ret, QAction): #print item.nodeKey() self.deleteNodeView(item.nodeKey()) break def _init_sample_scene(self): self._addNode(self._registeredNodeTypes.index('Image from disk'), QPoint(-250,0)) self._addNode(self._registeredNodeTypes.index('Grayscale'), QPoint(-40,50)) self._addNode(self._registeredNodeTypes.index('Gaussian blur'), QPoint(150,100)) self._addNode(self._registeredNodeTypes.index('Mixture of Gaussians'), QPoint(350,150)) self._addNode(self._registeredNodeTypes.index('Preview window'), QPoint(600,100))
def __init__(self): super(visualSpiceWindow, self).__init__() # generate TEMP DIR for simulations try: shutil.rmtree(Config.TEMP_DIR) except Exception as e: # no templfile to delete pass finally: Path(Config.TEMP_DIR).mkdir(parents=True, exist_ok=True) uic.loadUi(Config.getResource("ui/main.ui"), self) self.setWindowTitle("visualSpice") self.setGeometry(50, 50, 800, 600) # Set Window to screen center geometry = self.frameGeometry() screen = QtWidgets.QApplication.desktop().screenNumber( QtWidgets.QApplication.desktop().cursor().pos()) center = QtWidgets.QApplication.desktop().screenGeometry( screen).center() geometry.moveCenter(center) self.move(geometry.topLeft()) # add Plot Viewer self.plotViewer = PlotViewer.PlotViewer(self) self.plotDockWidget.setWidget(self.plotViewer.win) # add nodeScene self.mainNodeScene = NodeScene.NodeScene() self.sceneTabWidget.addTab(self.mainNodeScene, "Main") self.mainNodeScene.signal_NodeSelected.connect(self._nodeSelected) self.mainNodeScene.signal_NodeDeleted.connect(self._nodeDeleted) # populate toolbar self.addDataInBtn = QtWidgets.QPushButton( QtGui.QIcon(Config.getResource("assets/add_data.png")), "Daten") self.addDataInBtn.clicked.connect(self.addData) self.addNewSimBtn = QtWidgets.QPushButton( QtGui.QIcon(Config.getResource("assets/add_sim.png")), "Simulation") self.addNewSimBtn.clicked.connect(self.addNewSim) self.addNewViewBtn = QtWidgets.QPushButton( QtGui.QIcon(Config.getResource("assets/add_plot.png")), "Plot") self.addNewViewBtn.clicked.connect(self.addNewPlot) self.deleteSelectedBtn = QtWidgets.QPushButton( QtGui.QIcon(Config.getResource("assets/delete.png")), "Löschen") self.deleteSelectedBtn.clicked.connect(self.deleteSelected) self.deleteSelectedBtn.setDisabled(True) self.focusBtn = QtWidgets.QPushButton( QtGui.QIcon(Config.getResource("assets/focus.png")), "Focus") self.focusBtn.clicked.connect( lambda: self.sceneTabWidget.currentWidget()._focus()) self.settingsBtn = QtWidgets.QPushButton( QtGui.QIcon(Config.getResource("assets/settings.png")), "Einstellungen") self.settingsBtn.clicked.connect(self._showSettings) self.runSimBtn = QtWidgets.QPushButton( QtGui.QIcon(Config.getResource("assets/start.png")), "Start") self.runSimBtn.clicked.connect(self.run) self.toolBar.addWidget(self.addDataInBtn) self.toolBar.addWidget(self.addNewSimBtn) self.toolBar.addWidget(self.addNewViewBtn) self.toolBar.addWidget(self.deleteSelectedBtn) self.toolBar.addSeparator() self.toolBar.addWidget(self.focusBtn) self.toolBar.addWidget(self.settingsBtn) spacer = QtWidgets.QWidget() spacer.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) self.toolBar.addWidget(spacer) self.toolBar.addSeparator() self.toolBar.addWidget(self.runSimBtn) self.show()
class NodeController(QObject): # These ones goes to model _registeredNodeTypes = ['Image from disk', 'Gaussian blur', \ 'Preview window', 'Grayscale', 'Mixture of Gaussians'] _nodeId = 0 def __init__(self, parent=None): QObject.__init__(self, parent) self._nodeViews = {} self._linkViews = [] self._scene = NodeScene(self) # !TODO: Temporary self._scene.setSceneRect(-200, -200, 1000, 600) # !TODO: Move to some initialize method self._view = NodeEditorView() self._view.setScene(self._scene) self._view.setGeometry(100, 50, 1200, 800) self._view.contextMenu.connect(self.contextMenu) self._view.show() self._addNodesActions = [] for item in enumerate(self._registeredNodeTypes): a = QAction(item[1], self) a.setData(item[0]) self._addNodesActions.append(a) ''' Zwraca widok wezla o podanym kluczu ID ''' def nodeView(self, key): return self._nodeViews[key] ''' Dodaje nowy widok wezla ''' def addNodeView(self, key, title): node = NodeView(title) node.setData(NodeDataIndex.NodeKey, key) #node.installEventFilter(self.nodeManager) self._nodeViews[key] = node self._scene.addItem(node) return node ''' Usuwa widok wezla o podanym kluczu ID ''' def deleteNodeView(self, key): print 'deleting node with key:', key # if key in self._nodeViews: # print 'deleting node with key: {0}'.format(key) # nodeView = self._nodeViews.pop(key) # # !TODO: Nie pamietam juz czy logika sie tym zajmie czy nie # # - chodzi o usuniecie wiszacych polaczen # lvs = filter(lambda lv: lv.connecting(nodeView), self._linkViews) # for link in lvs: # link.dtor() # self._linkViews.remove(link) # self._scene.removeItem(nodeView) # return True # else: # print 'node with key: {0} not found'.format(key) # return False ''' Zwraca liste polaczen wchodzacych do danego wezla ''' def inputLinkViews(self, nodeKey): if nodeKey in self._nodeViews: nv = self._nodeViews[nodeKey] return filter(lambda lv: lv.inputConnecting(nv), self._linkViews) return None ''' Zwraca liste polaczen wychodzacych z danego wezla ''' def outputLinkViews(self, nodeKey): if nodeKey in self._nodeViews: nv = self._nodeViews[nodeKey] return filter(lambda lv: lv.outputConnecting(nv), self._linkViews) return None ''' Tworzy nowe (wizualne) polaczenie miedzy danymi gniazdami ''' def linkNodeViews(self, fromSocketView, toSocketView): # TODO!: To bedzie w logice # Check if we aren't trying to create already existing connection for linkView in self._linkViews: if linkView.connects(fromSocketView, toSocketView): QMessageBox.critical(None, 'NodeView', 'Connection already exists') return link = NodeLinkView(fromSocketView, toSocketView, None) link.setDrawDebug(DEBUG_LINKS) fromSocketView.addLink(link) toSocketView.addLink(link) self._linkViews.append(link) #link.installEventFilter(self.nodeManager) self._scene.addItem(link) ''' Usuwa polaczenie (wizualne) miedzy danymi gniazdami ''' def unlinkNodeViews2(self, fromSocketView, toSocketView): for linkView in self._linkViews: if linkView.connects(fromSocketView, toSocketView): self._scene.removeItem(linkView) self._linkViews.remove(linkView) return True return False def unlinkNodeViews(self, linkView): pass # Normalnie, za to odpowiedzialna jest logika def _addNode(self, nodeTypeId, scenePos): if nodeTypeId < len(self._registeredNodeTypes): title = self._registeredNodeTypes[nodeTypeId] nodeId = self._nodeId node = self.addNodeView(nodeId, title) node.setPos(scenePos) if title == 'Image from disk': node.addSocketView(0, 'Output', True) elif title == 'Gaussian blur': node.addSocketView(0, 'Input') node.addSocketView(1, 'Sigma') node.addSocketView(0, 'Output', True) elif title == 'Preview window': node.addSocketView(0, 'Input') elif title == 'Grayscale': node.addSocketView(0, 'Input') node.addSocketView(0, 'Output', True) elif title == 'Mixture of Gaussians': node.addSocketView(0, 'Frame') node.addSocketView(0, 'Foreground mask', True) self._nodeId += 1 ''' Reakcja na opuszczenie nowego polaczenia ''' @Slot(NodeSocketView, NodeSocketView) def draggingLinkDropped(self, fromSocketView, toSocketView): self.linkNodeViews(fromSocketView, toSocketView) @Slot(NodeSocketView) def draggingLinkStarted(self, fromSocketView): self._scene.dragging = True #print 'dragging started from', fromSocketView @Slot(NodeSocketView) def draggingLinkStopped(self, fromSocketView): self._scene.dragging = False #print 'dragging stopped' ''' Reakcja na probe pokazania menu kontekstowego pochodzacego z widoku sceny ''' @Slot(QPoint, QPointF) def contextMenu(self, globalPos, scenePos): items = self._scene.items(scenePos, Qt.ContainsItemShape, Qt.AscendingOrder) # If we clicked onto empty space if not items: menu = QMenu() menuAddNode = menu.addMenu('Add node') for a in self._addNodesActions: menuAddNode.addAction(a) ret = menu.exec_(globalPos) if ret is not None: self._addNode(ret.data(), scenePos) else: for item in items: if item.type() == NodeView.Type: menu = QMenu() action = QAction('Delete node', None) action.setData(10) menu.addAction(action) ret = menu.exec_(globalPos) if ret is not None and isinstance(ret, QAction): #print item.nodeKey() self.deleteNodeView(item.nodeKey()) break def _init_sample_scene(self): self._addNode(self._registeredNodeTypes.index('Image from disk'), QPoint(-250, 0)) self._addNode(self._registeredNodeTypes.index('Grayscale'), QPoint(-40, 50)) self._addNode(self._registeredNodeTypes.index('Gaussian blur'), QPoint(150, 100)) self._addNode(self._registeredNodeTypes.index('Mixture of Gaussians'), QPoint(350, 150)) self._addNode(self._registeredNodeTypes.index('Preview window'), QPoint(600, 100))