def pasteItem(self, mousePos=None): """ 粘贴项目 从剪贴板中拿到带边的节点数据,替换原有id后,交给CommandAdd处理, """ if not GraphisClipboard().hasGraphicsItems(): return itemDatasWithEdge = GraphisClipboard().graphicsItems() controller = ControllerManager().getController(self.controllerKey) # 生成和替换id old2NewIds = {} for itemData in itemDatasWithEdge: oldId = itemData['node']['id'] newId = controller.genUUID() old2NewIds[oldId] = newId self.replaceWithIdMap(itemDatasWithEdge, old2NewIds) command = CommandAdd(self, itemDatasWithEdge, description='add one/serveral items', mousePosition=mousePos) self.undoStack.push(command)
def directConnection(self, startItem, endItem): """ 直接建立连接,不做任何检查 """ controller = ControllerManager().getController(self.controllerKey) arrow = CosineConnection(startItem, endItem) # print 'start type', startItem.itemContent.contentType if startItem.itemContent.contentType != 'Any': arrow.setConnectionType(startItem.itemContent.contentType) arrow.setColor(startItem.itemContentColor) else: arrow.setConnectionType(endItem.itemContent.contentType) arrow.setColor(endItem.itemContentColor) # controller.addEdge(startItem.parentItem(), # endItem.parentItem(), # startItem.itemType, # endItem.itemType, # startItem.itemContent.contentType) controller.addEdge(startItem.parentItem(), endItem.parentItem(), startItem.itemType, endItem.itemType, arrow.connectionType) startItem.addArrow(arrow) endItem.addArrow(arrow) arrow.setZValue(-1000.0) self.addItem(arrow) arrow.updatePosition() # 连线后不再具有值 endItem.itemContent.contentValue = None startItem.update() endItem.update() self.editSignal.emit()
def __init__(self, parent=None): super(GraphWidget, self).__init__(parent) self.editFlag = False # 未在编辑转态 self.controllerKey = ControllerManager().addController() self.sceneWidth = 10000 self.sceneHeight = 10000 self.bindingFile = None # 创建图形场景对象,传递控制键参数 self.scene = DiagramScene(self.controllerKey) self.scene.setSceneRect( QRectF(-self.sceneWidth / 2.0, -self.sceneHeight / 2.0, self.sceneWidth, self.sceneHeight)) # 将信号itemSelected连接到指定槽函数 self.scene.itemSelected.connect(self.itemSelected) self.scene.resetModeSignal.connect(self.modeReseted) self.scene.editSignal.connect(self.sceneEdited) # 创建图形视口对象,传入图形场景作为对象参数 self.view = DiagramView(self.scene) # self.view.setBackgroundBrush(QColor(230, 200, 167)) # self.view.setBackgroundBrush(QColor(41, 41, 41)) self.view.setMouseTracking(True) # 视图鼠标跟踪 # 创建水平布局管理器对象 layout = QHBoxLayout() # 视图控件对象添加到布局管理器中 layout.addWidget(self.view) # 把布局管理器设置给需要布局的父控件 self.setLayout(layout) # 空白控件,新建节点快捷栏 self.blankWidget = QuickDockWidget() self.blankWidget.setParent(self) self.blankWidget.resize(900, 80) self.blankWidget.show() self.blankWidget.raise_() self.blankWidget.hide() # 默认掩藏节点快捷栏 self.findResult = set() self.findResultItems = [] self.targetNode = None self.prevNodeList = [] self.nextNodeList = [] self.prevEdgeList = [] self.nextEdgeList = [] controller = ControllerManager().getController(self.controllerKey) controller.setScene(self.scene) self.nameIndex = {} self.valueIndex = {} self.commentIndex = {} self.allNodes = set() self.logger = logger.getLogger('GraphWidget')
def findNodeByArgValue(self, nodeName, argName, searchValue, chosenNodes=None): # chosenNodes is used by replace in several selected nodes controller = ControllerManager().getController(self.controllerKey) return controller.findNodeByArgValue(nodeName, argName, searchValue, chosenNodes)
def redo(self): controller = ControllerManager().getController(self.controllerKey) for itemData in self.data: # 先删除边 inEdgesData = itemData['inEdgeData'] outEdgesData = itemData['outEdgeData'] # 删除入边 for edgeData in inEdgesData: startParent = self.scene.cache.get(edgeData['start'], None) if startParent is None: continue endParent = self.scene.cache.get(edgeData['end'], None) startItem = self.scene.findSubItem(startParent, edgeData['startItemTypeId']) endItem = self.scene.findSubItem(endParent, edgeData['endItemTypeId']) if startItem is None or endItem is None: continue for arrow in endItem.arrows[:]: if arrow.startItem().parentItem().uuid == edgeData['start'] and \ arrow.startItem().itemType.typeId == startItem.itemType.typeId: self.scene.simpleDisconnection(arrow) break # 删除出边 for edgeData in outEdgesData: endParent = self.scene.cache.get(edgeData['end'], None) if endParent is None: continue startParent = self.scene.cache.get(edgeData['start'], None) startItem = self.scene.findSubItem(startParent, edgeData['startItemTypeId']) endItem = self.scene.findSubItem(endParent, edgeData['endItemTypeId']) if startItem is None or endItem is None: continue for arrow in startItem.arrows[:]: if arrow.endItem().parentItem().uuid == edgeData['end'] and \ arrow.endItem().itemType.typeId == endItem.itemType.typeId: self.scene.simpleDisconnection(arrow) break # 删除节点 iD = itemData['node']['id'] item = self.scene.cache.get(iD, None) if item is None: continue controller.removeNode(item) self.scene.removeItem(item) self.scene.removeFromCache(item)
def addDiagramItem(self, scenePos): controller = ControllerManager().getController(self.controllerKey) data = {'type': '%s' % controller.selectedItemType.typeId} data.update({'pos': {'x': scenePos.x(), 'y': scenePos.y()}}) command = CommandAdd(self, data) self.undoStack.push(command) # 跟踪计数 ControllerManager().tracker.trackAdd( controller.selectedItemType.typeId) self.resetMode()
def undo(self): controller = ControllerManager().getController(self.controllerKey) for itemData in self.data: item = controller.genItemWithData(itemData['node']) pos = QPointF(itemData['node']['pos']['x'], itemData['node']['pos']['y']) self.scene.addItem(item) item.setPos(pos) item.setSelected(True) controller.addNode(item) self.scene.addToCache(item) # 智能恢复边 for itemData in self.data: inEdgesData = itemData['inEdgeData'] outEdgesData = itemData['outEdgeData'] # 恢复入边 for edgeData in inEdgesData: startParent = self.scene.cache.get(edgeData['start'], None) if startParent is None: # 可插入debug信息 continue endParent = self.scene.cache.get(edgeData['end'], None) startItem = self.scene.findSubItem(startParent, edgeData['startItemTypeId']) endItem = self.scene.findSubItem(endParent, edgeData['endItemTypeId']) if startItem is None or endItem is None: continue # 建立边 self.scene.simpleMakeConnection(startItem, endItem) # 恢复出边 for edgeData in outEdgesData: endParent = self.scene.cache.get(edgeData['end'], None) if endParent is None: continue startParent = self.scene.cache.get(edgeData['start'], None) startItem = self.scene.findSubItem(startParent, edgeData['startItemTypeId']) endItem = self.scene.findSubItem(endParent, edgeData['endItemTypeId']) if startItem is None or endItem is None: continue # 建立边 self.scene.simpleMakeConnection(startItem, endItem)
def find(self): print('in widget find') controller = ControllerManager().getController(self.controllerKey) if not self.nameIndex: self.nameIndex = controller.invertIndexByName() self.valueIndex = controller.invertIndexByValue() self.commentIndex = controller.invertIndexByComment() nodes = controller.nodes for node in nodes: self.allNodes.add(node) dlg = FindDialog(self) dlg.show()
def freeComment(self): view = self.views()[0] sz = view.size() width, height = sz.width(), sz.height() topLeft = view.mapToScene(0, 0) topLeftF = QPointF(topLeft.x(), topLeft.y()) fCommentPos = topLeftF + QPointF(width / 3, height / 3) freec = FreeCommentItem('自由注释') self.addItem(freec) freec.setPos(fCommentPos) controller = ControllerManager().getController(self.controllerKey) controller.addFreeComment(freec)
def simpleMakeConnection(self, startItem, endItem): """ 不带Undo/Redo功能的建立连接,做必要的检查 """ if not mechanism.canConnect(startItem, endItem): return controller = ControllerManager().getController(self.controllerKey) if endItem.itemContent.contentType == 'Event': # Event,可以有任意多的入边 self.directConnection(startItem, endItem) else: # 别的类型,只能有一条入边 # 且后续如果有别的边想要连入,必须删除之前连入的边 if len(endItem.arrows) == 0: # 没有连入的边 self.directConnection(startItem, endItem) else: # 有连入的边,删除原来的边 oldArrow = endItem.arrows[0] delCommand = CommandUnLink(controller, oldArrow, description='remove an arrow') self.undoStack.push(delCommand) # 在添加新边 self.directConnection(startItem, endItem) self.editSignal.emit()
def replace(self): self.logger.debug('Start Replacing') targetNodes = self.scene.getSelectedNodes() targetNodes = targetNodes if targetNodes else ControllerManager( ).getController(self.controllerKey).nodes dlg = ReplaceDialog(targetNodes, self) dlg.show()
def closeWidget(self, scriptsData): if self.bindingFile is not None: scriptname = '%s' % os.path.splitext( os.path.split(self.bindingFile)[-1])[0] if scriptsData.get(scriptname, None): del scriptsData[scriptname] ControllerManager().removeController(self.controllerKey) self.blankWidget.timer.stop()
def createContextMenu(self): """创建右键菜单栏""" self.menu = QMenu() menuTreeData = ControllerManager().menuTree.tree self.genDynamicMenu(menuTreeData, self.menu) for submenu in self.menu.children()[1:]: if submenu.isEmpty(): self.menu.removeAction(submenu.menuAction())
def runGraph(self): controller = ControllerManager().getController(self.controllerKey) self.uuidIndex = {node.uuid: node for node in controller.nodes} data = controller.getData() config_data = single_file_export(data) if self.process and self.process.is_alive(): self.killChildProcess() # 开启爬虫子进程 from run import crawl self.parent_conn.send(self.spinBoxValue) # 模块间隔时间 self.process = multiprocessing.Process(target=crawl, args=(config_data, self.child_conn)) self.startSlot() # 初始设置 self.process.start()
def initButtons(self, parentLayout): self.bindingItems = ControllerManager().tracker.topItems(6) self.buttons = [] for i in range(6): btn = QPushButton(self.bindingItems[i].typeName) btn.clicked.connect(partial(self.chooseWidgetClicked, i)) self.buttons.append(btn) for btn in self.buttons: parentLayout.addWidget(btn)
def simpleDisconnection(self, arrow): """ 简单地删除连接,不包含Undo/Redo功能 """ controller = ControllerManager().getController(self.controllerKey) controller.removeEdge(arrow.startItem().parentItem(), arrow.endItem().parentItem(), arrow.startItem().itemType.typeId, arrow.endItem().itemType.typeId) arrow.startItem().removeArrow(arrow) arrow.endItem().removeArrow(arrow) # 恢复默认值 arrow.endItem().itemContent.contentValue = arrow.endItem( ).itemContent.defaultValue arrow.startItem().update() arrow.endItem().update() self.removeItem(arrow) self.editSignal.emit()
def deleteSelectedItems(self): """ 删除所选择的items,先删除边,后删除节点, """ edgesData = [] controller = ControllerManager().getController(self.controllerKey) for item in self.selectedItems(): if isinstance(item, ConnectionBase): if item.startItem().parentItem().isSelected() or item.endItem( ).parentItem().isSelected(): continue edgeData = { 'start': item.startItem().parentItem().uuid, 'end': item.endItem().parentItem().uuid, 'startItemTypeId': item.startItem().itemType.typeId, 'endItemTypeId': item.endItem().itemType.typeId } edgesData.append(edgeData) if len(edgesData) != 0: command = CommandUnLink(self, edgesData, description='remove an/serveral arrows') self.undoStack.push(command) itemDatasWithEdge = [] for item in self.selectedItems(): if isinstance(item, DiagramItem): itemData = self.itemToDataWithEdge(item) itemDatasWithEdge.append(itemData) elif isinstance(item, FreeCommentItem): controller.removeFreeComment(item) self.removeItem(item) if len(itemDatasWithEdge) != 0: command = CommandDelete(self, itemDatasWithEdge, description='delete an or serveral items') self.undoStack.push(command)
def undo(self): controller = ControllerManager().getController(self.controllerKey) for edgeData in self.data: startParent = self.scene.cache.get(edgeData['start'], None) endParent = self.scene.cache.get(edgeData['end'], None) startItem = self.scene.findSubItem(startParent, edgeData['startItemTypeId']) endItem = self.scene.findSubItem(endParent, edgeData['endItemTypeId']) if startItem is None or endItem is None: continue self.scene.directConnection(startItem, endItem)
def runGraph(self): controller = ControllerManager().getController(self.controllerKey) data = controller.getData() config_data = single_file_export(data) # self.thread = CrawlThread(config_data) # 创建线程 # self.thread.started.connect(lambda: print('=========== Starting Crawl ==========')) # self.thread.start() # self.thread.finished.connect(lambda: print("============ Done ================")) # 开启爬虫子 from crawler_graph.crawler import crawl import multiprocessing try: process = multiprocessing.Process(target=crawl, args=(config_data, )) process.start() except Exception as e: print(f'Crawler Error: {e}') # 开启爬虫子进程 obj_file = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'crawler_graph', 'TestOne.py') # obj_file = resource_path(obj_file) self.process = QProcess(self) self.process.readyReadStandardOutput.connect(self.stdoutReady) self.process.readyReadStandardError.connect(self.stderrReady) # start_time = datetime.now() self.process.started.connect( lambda: print('********* Started! **********')) self.process.finished.connect( lambda: print('********** Finished! *** Timer: {} *********'. format(datetime.now() - start_time))) self.process.start('python', [obj_file, str(config_data)])
def undo(self): controller = ControllerManager().getController(self.controllerKey) for edgeData in self.data: startParent = self.scene.cache.get(edgeData['start'], None) endParent = self.scene.cache.get(edgeData['end'], None) startItem = self.scene.findSubItem(startParent, edgeData['startItemTypeId']) endItem = self.scene.findSubItem(endParent, edgeData['endItemTypeId']) if startItem is None or endItem is None: continue for arrow in startItem.arrows[:]: if arrow.endItem().parentItem().uuid == edgeData['end'] and \ arrow.endItem().itemType.typeId == endItem.itemType.typeId: self.scene.simpleDisconnection(arrow) break
def highLightResult(self, curResultIndex): controller = ControllerManager().getController(self.controllerKey) self.targetNode = self.findResultItems[curResultIndex] self.prevNodeList = controller.getPrevNode(self.targetNode) self.nextNodeList = controller.getNextNode(self.targetNode) self.prevEdgeList = controller.getPrevEdge(self.targetNode) self.nextEdgeList = controller.getNextEdge(self.targetNode) self.scene.locateFind(self.targetNode) self.scene.locateFindNode(self.prevNodeList, self.nextNodeList) self.scene.locateFindEdge(self.prevEdgeList, self.nextEdgeList) print(('find at (%.1f, %.1f)' % (self.targetNode.x(), self.targetNode.y())))
def highLightNode(self, node): # for replace controller = ControllerManager().getController(self.controllerKey) self.targetNode = node self.prevNodeList = controller.getPrevNode(self.targetNode) self.nextNodeList = controller.getNextNode(self.targetNode) self.prevEdgeList = controller.getPrevEdge(self.targetNode) self.nextEdgeList = controller.getNextEdge(self.targetNode) self.scene.locateFind(self.targetNode) self.scene.locateFindNode(self.prevNodeList, self.nextNodeList) self.scene.locateFindEdge(self.prevEdgeList, self.nextEdgeList) self.logger.info('find at (%.1f, %.1f)' % (self.targetNode.x(), self.targetNode.y()))
def itemToData(self, item, center): controller = ControllerManager().getController(self.controllerKey) itemData = controller.nodeToData(item, center) return itemData
def getArgsNameInNode(self, nodeName): nodes = ControllerManager().itemData for node in nodes: if nodeName == node['name'][0]: return [arg['name'][0] for arg in node['args']] return []
def openGraph(self, filename): controller = ControllerManager().getController(self.controllerKey) controller.restoreFromData(self.scene, filename=filename) self.updateEdit(False)
def saveGraph(self, filename): controller = ControllerManager().getController(self.controllerKey) controller.saveGraph(filename=filename) if filename != self.bindingFile: self.bindingFile = filename self.updateEdit(False)
def getScriptJsonData(self): controller = ControllerManager().getController(self.controllerKey) data = controller.getData() return data
def restoreFromData(self, filename): controller = ControllerManager().getController(self.controllerKey) if controller.restoreFromData(self.scene, filename=filename): self.bindingFile = filename self.updateEdit(False)
def refresh(self): self.bindingItems = ControllerManager().tracker.topItems(6) for i in range(len(self.buttons)): self.buttons[i].setText(self.bindingItems[i].typeName)
def itemToDataWithEdge(self, item, center=None): controller = ControllerManager().getController(self.controllerKey) itemDataWithEdge = controller.nodeToDataWithEdge(item, center) return itemDataWithEdge