Пример #1
0
    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')
Пример #2
0
    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()
Пример #3
0
    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()
Пример #4
0
    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)
Пример #5
0
 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()
Пример #6
0
    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()
Пример #7
0
 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()
Пример #8
0
    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())
Пример #9
0
 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)
Пример #10
0
    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)
Пример #11
0
    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)
Пример #12
0
 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()
Пример #13
0
    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)
Пример #14
0
    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())))
Пример #15
0
    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)
Пример #16
0
    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)
Пример #17
0
    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()))
Пример #18
0
    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
Пример #19
0
    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()
Пример #20
0
    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()
Пример #21
0
    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)
Пример #22
0
    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)])
Пример #23
0
    def itemToData(self, item, center):
        controller = ControllerManager().getController(self.controllerKey)
        itemData = controller.nodeToData(item, center)

        return itemData
Пример #24
0
 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 []
Пример #25
0
 def openGraph(self, filename):
     controller = ControllerManager().getController(self.controllerKey)
     controller.restoreFromData(self.scene, filename=filename)
     self.updateEdit(False)
Пример #26
0
 def saveGraph(self, filename):
     controller = ControllerManager().getController(self.controllerKey)
     controller.saveGraph(filename=filename)
     if filename != self.bindingFile:
         self.bindingFile = filename
     self.updateEdit(False)
Пример #27
0
 def restoreFromData(self, filename):
     controller = ControllerManager().getController(self.controllerKey)
     if controller.restoreFromData(self.scene, filename=filename):
         self.bindingFile = filename
         self.updateEdit(False)
Пример #28
0
 def getScriptJsonData(self):
     controller = ControllerManager().getController(self.controllerKey)
     data = controller.getData()
     return data
Пример #29
0
 def refresh(self):
     self.bindingItems = ControllerManager().tracker.topItems(6)
     for i in range(len(self.buttons)):
         self.buttons[i].setText(self.bindingItems[i].typeName)
Пример #30
0
    def itemToDataWithEdge(self, item, center=None):
        controller = ControllerManager().getController(self.controllerKey)
        itemDataWithEdge = controller.nodeToDataWithEdge(item, center)

        return itemDataWithEdge