def addSubgraph(self, parent_graph, subgraph_name, subgraph_type=GraphType.SimpleGraph, **kwargs): subgraph = Graph(subgraph_name, subgraph_type, parent_graph, **kwargs) subgraph.name = subgraph_name subgraph.parent_graph = parent_graph parent_graph.nodes.append(subgraph) return subgraph
def addNewRelationshipToGraph(self, graph, relationshipLabel, parent, child): #retrive node objects given node names parentNode = Graph.findNode(self.qgv.engine.graph, parent) childNode = Graph.findNode(self.qgv.engine.graph, child) #add edge to graph self.qgv.addEdge(parentNode, childNode, {"label": relationshipLabel}) self.qgv.build() #update json file to keep track of all edges fname = "ui/windows/graph.json" self.qgv.saveAsJson(fname) self.mdiArea.setActiveSubWindow(self.graphSubWin)
def display_graph(vector): x = UI.graph_ui graph = x.graph graph.engine.graph = Graph("MainGraph") graph.build() graph.repaint() nodes = {} for log in AA.vector[vector].log_visible: le = AA.log_entries[log] nodes[le.id] = graph.addNode(graph.engine.graph, "Node", label=le.id + '\n' + le.name, fillcolor=le.type) tbl_rel = UI.relationships_ui.tbl_relationships for row in range(tbl_rel.rowCount()): try: node1 = AA.log_entries[tbl_rel.item(row, 0).text()].id node2 = AA.log_entries[tbl_rel.item(row, 1).text()].id graph.addEdge(nodes[node1], nodes[node2], { "width": 5, "color": "black" }) except: pass x.graph.build()
def setupGraph(self): graph = self.ui.graph qgv = QGraphViz( # show_subgraphs=show_subgraphs, # node_selected_callback=node_selected, # edge_selected_callback=edge_selected, # node_invoked_callback=node_invoked, # edge_invoked_callback=edge_invoked, ) qgv.new(Dot(Graph("Main_Graph"))) n1 = qgv.addNode(qgv.engine.graph, "Node1", label="N1") n2 = qgv.addNode(qgv.engine.graph, "Node2", label="N2") n3 = qgv.addNode(qgv.engine.graph, "Node3", label="N3") n4 = qgv.addNode(qgv.engine.graph, "Node4", label="N4") n5 = qgv.addNode(qgv.engine.graph, "Node5", label="N5") n6 = qgv.addNode(qgv.engine.graph, "Node6", label="N6") qgv.addEdge(n1, n2, {}) qgv.addEdge(n3, n2, {}) qgv.addEdge(n2, n4, {"width": 2}) qgv.addEdge(n4, n5, {"width": 4}) qgv.addEdge(n4, n6, {"width": 5, "color": "red"}) qgv.addEdge(n3, n6, {"width": 2}) # Build the graph (the layout engine organizes where the nodes and connections are) qgv.build() qgv.save("test.gv") graph.layout().addWidget(qgv)
def read_vector_table(self, vector): """checks if there is information in the node and relationship tables and either displays an empty graph or calls update_graph() if there are elements in the tables""" if (vector == None): qgv = self.qgv show_subgraphs = True qgv.setStyleSheet("background-color:white;") # Create A new Graph using Dot layout engine qgv.new(Dot(Graph("Main_Graph"), show_subgraphs=show_subgraphs)) # Define some graph n1 = qgv.addNode(qgv.engine.graph, "Node1", label="Nothing to show", fillcolor="white") # Build the graph (the layout engine organizes where the nodes and connections are) qgv.build() # Save it to a file to be loaded by Graphviz if needed qgv.save("./gv/test.gv") # Add the QGraphViz object to the layout self.layout_u.addWidget(qgv) self.qgv = qgv else: self.update_graph(vector)
def Graphics(self, x, y): item = QGraphViz( window, auto_freeze=True, hilight_Nodes=True, ) item.setStyleSheet("background-color:white;") item.new( Dot(Graph("Main_Graph"), font=QFont("Arial", 12), margins=[40, 40])) item.move(x, y) item.resize(1150, 500) self.widgets.append(item) return item
def new(): self.qgv.engine.graph = Graph("MainGraph") self.qgv.build() self.qgv.repaint() #clear all data from nodes table widget rowCount = self.tableWidgetNodes.rowCount() for x in range(1, rowCount): self.tableWidgetNodes.removeRow(x) self.tableWidgetNodes.removeRow(1) #clear all data from relationships table widget rowCount = self.tableWidgetRelationships.rowCount() for x in range(rowCount): self.tableWidgetRelationships.removeRow(x) #update json file fname = "ui/windows/graph.json" self.qgv.saveAsJson(fname)
def setupUi(self, graphWindow): self.graphWin = graphWindow.setObjectName("graphWindow") graphWindow.setObjectName("graphWindow") graphWindow.resize(1155, 895) graphWindow.setDockNestingEnabled(True) self.centralwidget = QtWidgets.QWidget(graphWindow) self.centralwidget.setObjectName("centralwidget") self.gridLayout = QtWidgets.QGridLayout(self.centralwidget) self.gridLayout.setObjectName("gridLayout") self.configuration = Configuration.get_instance() #*-----------------------vector selection objects------------------------------------------------*# self.groupBoxVectorSelection = QtWidgets.QGroupBox(self.centralwidget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.groupBoxVectorSelection.sizePolicy().hasHeightForWidth()) self.groupBoxVectorSelection.setSizePolicy(sizePolicy) self.groupBoxVectorSelection.setObjectName("groupBoxVectorSelection") self.gridLayout.addWidget(self.groupBoxVectorSelection, 0, 0, 1, 1) self.formLayoutVector = QtWidgets.QHBoxLayout( self.groupBoxVectorSelection) self.formLayoutVector.setObjectName("formLayoutVector") #vector label self.labelVector = QtWidgets.QLabel(self.groupBoxVectorSelection) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.labelVector.sizePolicy().hasHeightForWidth()) self.labelVector.setSizePolicy(sizePolicy) self.labelVector.setObjectName("labelVector") self.formLayoutVector.addWidget(self.labelVector) #vector combo box self.comboBoxVector = QtWidgets.QComboBox(self.groupBoxVectorSelection) self.comboBoxVector.setMinimumSize(QtCore.QSize(150, 0)) self.comboBoxVector.setMaximumSize(QtCore.QSize(69, 16777215)) self.comboBoxVector.setObjectName("comboBoxVector") self.formLayoutVector.addWidget(self.comboBoxVector) self.comboBoxVector.addItem("None") self.vectorList = Configuration.get_list_of_vector_dicts( self.configuration) for vector in self.vectorList: self.comboBoxVector.addItem(vector["name"]) #vector description label self.labelVectorDesc = QtWidgets.QLabel(self.groupBoxVectorSelection) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.labelVectorDesc.sizePolicy().hasHeightForWidth()) self.labelVectorDesc.setSizePolicy(sizePolicy) self.labelVectorDesc.setObjectName("labelVectorDesc") self.formLayoutVector.addWidget(self.labelVectorDesc) #vector description line edit self.lineEditVectorDesc = QtWidgets.QLineEdit( self.groupBoxVectorSelection) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.lineEditVectorDesc.sizePolicy().hasHeightForWidth()) self.lineEditVectorDesc.setSizePolicy(sizePolicy) self.lineEditVectorDesc.setReadOnly(True) self.lineEditVectorDesc.setObjectName("lineEditVectorDesc") self.formLayoutVector.addWidget(self.lineEditVectorDesc) self.comboBoxVector.currentTextChanged.connect( lambda: self.changeVector()) #*----------------------multi-document-area---------------------------------------------------------------*# self.mdiArea = QtWidgets.QMdiArea(self.centralwidget) self.mdiArea.setLayoutDirection(QtCore.Qt.LeftToRight) self.mdiArea.setFrameShape(QtWidgets.QFrame.StyledPanel) self.mdiArea.setSizeAdjustPolicy( QtWidgets.QAbstractScrollArea.AdjustIgnored) self.mdiArea.setActivationOrder( QtWidgets.QMdiArea.ActivationHistoryOrder) self.mdiArea.setViewMode(QtWidgets.QMdiArea.SubWindowView) self.mdiArea.setDocumentMode(False) self.mdiArea.setTabsClosable(False) self.mdiArea.setTabsMovable(True) self.mdiArea.setTabShape(QtWidgets.QTabWidget.Rounded) self.mdiArea.setTabPosition(QtWidgets.QTabWidget.North) self.mdiArea.setObjectName("mdiArea") #*-------------------------Graph Subwindow------------------------------------------------------------------*# self.subwindow_Graph = QtWidgets.QWidget() self.subwindow_Graph.setLayoutDirection(QtCore.Qt.LeftToRight) self.subwindow_Graph.setObjectName("subwindow_Graph") self.gridLayout_3 = QtWidgets.QGridLayout(self.subwindow_Graph) self.gridLayout_3.setObjectName("gridLayout_3") # Interval Label and combo box self.IntervalLabel = QtWidgets.QLabel(self.subwindow_Graph) self.IntervalLabel.setObjectName("IntervalLabel") self.gridLayout_3.addWidget(self.IntervalLabel, 2, 1, 1, 1, QtCore.Qt.AlignRight) self.Interval = QtWidgets.QComboBox(self.subwindow_Graph) self.Interval.setObjectName("Interval") self.Interval.addItem("") # Select Interval self.Interval.addItem("") # Seconds self.Interval.addItem("") # Minutes self.Interval.addItem("") # Hours self.gridLayout_3.addWidget(self.Interval, 2, 2, 1, 1) #Timeline orientation label and combo box self.TimelineOrientationLabel = QtWidgets.QLabel(self.subwindow_Graph) self.TimelineOrientationLabel.setObjectName("TimelineOrientationLabel") self.gridLayout_3.addWidget(self.TimelineOrientationLabel, 2, 3, 1, 1, QtCore.Qt.AlignRight) self.TimelineOrientation = QtWidgets.QComboBox(self.subwindow_Graph) self.TimelineOrientation.setObjectName("TimelineOrientation") self.TimelineOrientation.addItem("") # Selection Orientation self.TimelineOrientation.addItem("") # Horizontal self.TimelineOrientation.addItem("") # Vertical self.gridLayout_3.addWidget(self.TimelineOrientation, 2, 4, 1, 1) self.newRelationshipFlag = False # Events def node_selected(node): if (self.qgv.manipulation_mode == QGraphVizManipulationMode.Node_remove_Mode): print("Node {} removed".format(node)) removeNode(node) else: print("Node selected {}".format(node)) if (self.newRelationshipFlag == True): update_json(node) self.newRelationshipFlag = False def edge_selected(edge): if (self.qgv.manipulation_mode == QGraphVizManipulationMode.Edge_remove_Mode): print("Edge {} removed".format(edge)) removeRelationship(edge) else: print("Edge selected {}".format(edge)) def node_invoked(node): print("Node double clicked") def edge_invoked(node): print("Edge double clicked") def node_removed(node): print("Node removed") def edge_removed(node): print("Edge removed") # Create QGraphViz graph widget show_subgraphs = True self.qgv = QGraphViz(show_subgraphs=show_subgraphs, node_selected_callback=node_selected, edge_selected_callback=edge_selected, node_invoked_callback=node_invoked, edge_invoked_callback=edge_invoked, node_removed_callback=node_removed, edge_removed_callback=edge_removed, hilight_Nodes=True, hilight_Edges=True) self.nodeId = 0 self.relationshipId = 0 f = open('ui/windows/graph.json', 'r+') f.truncate(0) self.qgv.setStyleSheet("background-color:white;") # Create A new Graph using Dot layout engine self.qgv.new(Dot(Graph("Main_Graph"), show_subgraphs=show_subgraphs)) # Build the graph (the layout engine organizes where the nodes and connections are) self.qgv.build() # Save it to a file to be loaded by Graphviz if needed self.qgv.save("test.gv") # Create a widget to handle the QGraphViz object graphWidget = QWidget() graphWidget.setLayout(QVBoxLayout()) self.gridLayout_3.addWidget(graphWidget, 3, 0, 1, 6) # Add the QGraphViz object to the layout graphWidget.layout().addWidget(self.qgv) #Buttons Functionality def manipulate(): self.qgv.manipulation_mode = QGraphVizManipulationMode.Nodes_Move_Mode #export as a CSV file def save(): fname = QFileDialog.getSaveFileName(self.qgv, "Save", "", "*.csv") if (fname[0] != ""): self.qgv.save(fname[0]) print(fname[0]) #fname = QFileDialog.getSaveFileName(self.qgv, "Save", "", "*.gv") #if(fname[0]!=""): # self.qgv.save(fname[0]) def new(): self.qgv.engine.graph = Graph("MainGraph") self.qgv.build() self.qgv.repaint() #clear all data from nodes table widget rowCount = self.tableWidgetNodes.rowCount() for x in range(1, rowCount): self.tableWidgetNodes.removeRow(x) self.tableWidgetNodes.removeRow(1) #clear all data from relationships table widget rowCount = self.tableWidgetRelationships.rowCount() for x in range(rowCount): self.tableWidgetRelationships.removeRow(x) #update json file fname = "ui/windows/graph.json" self.qgv.saveAsJson(fname) def load(): fname = QFileDialog.getOpenFileName(self.qgv, "Open", "", "*.csv") if (fname[0] != ""): self.qgv.load_file(fname[0]) #populate json file with new graph fname = "ui/windows/graph.json" self.qgv.saveAsJson(fname) #open json file and load data with open('ui/windows/graph.json') as json_file: data = json.load(json_file) #iterate through each node and add it to the nodes table widget nodesData = data["nodes"] for node in nodesData: self.addNewNode( self.tableWidgetNodes, node["kwargs"]["id"], node["kwargs"]["label"], node["kwargs"]["timestamp"], node["kwargs"]["description"], node["kwargs"]["leReference"], node["kwargs"]["creator"], node["kwargs"]["shape"], node["kwargs"]["leSource"]) #iterate through each edge and add it to the relationships table widget relationshipsData = data["edges"] for edge in relationshipsData: try: label = edge["kwargs"]["label"] except KeyError: label = "" self.addTableData(self.tableWidgetRelationships, label, edge["source"], edge["dest"]) def add_node(): #add node dialog addNodeDialog = QDialog() addNodeDialog.ok = False addNodeDialog.node_name = "" addNodeDialog.node_label = "" addNodeDialog.node_timestamp = "" addNodeDialog.node_description = "" addNodeDialog.node_logEntryReference = "" addNodeDialog.node_logCreator = "" addNodeDialog.node_logEntrySource = "" addNodeDialog.node_type = "None" # Layouts main_layout = QVBoxLayout() addNodeLayout = QFormLayout() buttons_layout = QHBoxLayout() main_layout.addLayout(addNodeLayout) main_layout.addLayout(buttons_layout) addNodeDialog.setLayout(main_layout) #line edits leNodeName = QLineEdit() leNodeLabel = QLineEdit() teNodeDescription = QTextEdit() dtNodeTimestamp = QDateTimeEdit() dtNodeTimestamp.setDate(QtCore.QDate(2020, 1, 1)) dtNodeTimestamp.setCalendarPopup(True) leLogEntryReference = QLineEdit() cbxLogCreator = QComboBox() leLogEntrySource = QLineEdit() cbxNodeType = QComboBox() cbxImage = QComboBox() #buttons pbOK = QPushButton() pbCancel = QPushButton() cbxNodeType.addItems(["None", "circle", "box"]) cbxLogCreator.addItems(["None", "Red", "Blue", "White"]) cbxImage.addItem("None") self.iconList = Configuration.get_list_of_icon_dicts( self.configuration) for icon in self.iconList: cbxImage.addItem(icon["name"]) pbOK.setText("&OK") pbCancel.setText("&Cancel") addNodeLayout.setWidget(0, QFormLayout.LabelRole, QLabel("Node Name")) addNodeLayout.setWidget(0, QFormLayout.FieldRole, leNodeName) addNodeLayout.setWidget(1, QFormLayout.LabelRole, QLabel("Node Description")) addNodeLayout.setWidget(1, QFormLayout.FieldRole, teNodeDescription) addNodeLayout.setWidget(2, QFormLayout.LabelRole, QLabel("Node Timestamp")) addNodeLayout.setWidget(2, QFormLayout.FieldRole, dtNodeTimestamp) addNodeLayout.setWidget(3, QFormLayout.LabelRole, QLabel("Log Entry Reference")) addNodeLayout.setWidget(3, QFormLayout.FieldRole, leLogEntryReference) addNodeLayout.setWidget(4, QFormLayout.LabelRole, QLabel("Log Creator")) addNodeLayout.setWidget(4, QFormLayout.FieldRole, cbxLogCreator) addNodeLayout.setWidget(5, QFormLayout.LabelRole, QLabel("Log Entry Source")) addNodeLayout.setWidget(5, QFormLayout.FieldRole, leLogEntrySource) addNodeLayout.setWidget(6, QFormLayout.LabelRole, QLabel("Node Type")) addNodeLayout.setWidget(6, QFormLayout.FieldRole, cbxNodeType) addNodeLayout.setWidget(7, QFormLayout.LabelRole, QLabel("Node Image")) addNodeLayout.setWidget(7, QFormLayout.FieldRole, cbxImage) #ok button handler def ok(): addNodeDialog.OK = True addNodeDialog.node_name = leNodeName.text() addNodeDialog.node_label = leNodeName.text() addNodeDialog.node_timestamp = dtNodeTimestamp.text() addNodeDialog.node_description = teNodeDescription.toPlainText( ) addNodeDialog.node_logEntryReference = leLogEntryReference.text( ) addNodeDialog.node_logCreator = cbxLogCreator.currentText() addNodeDialog.node_logEntrySource = leLogEntrySource.text() if (cbxImage.currentText()): for icon in self.iconList: if (cbxImage.currentText() == icon["name"]): addNodeDialog.node_type = icon["source"] else: addNodeDialog.node_type = cbxNodeType.currentText() addNodeDialog.close() #cancel button handler def cancel(): addNodeDialog.OK = False addNodeDialog.close() pbOK.clicked.connect(ok) pbOK.clicked.connect(lambda: self.addNewNode( self.tableWidgetNodes, str(self.nodeId), leNodeName.text(), dtNodeTimestamp.text(), teNodeDescription.toPlainText(), leLogEntryReference.text(), cbxLogCreator.currentText(), addNodeDialog.node_type, leLogEntrySource.text())) pbCancel.clicked.connect(cancel) buttons_layout.addWidget(pbOK) buttons_layout.addWidget(pbCancel) addNodeDialog.exec_() if addNodeDialog.OK and addNodeDialog.node_name != '': self.qgv.addNode( self.qgv.engine.graph, addNodeDialog.node_name, id=str(self.nodeId), label=addNodeDialog.node_label, description=addNodeDialog.node_description, timestamp=addNodeDialog.node_timestamp, leReference=addNodeDialog.node_logEntryReference, creator=addNodeDialog.node_logCreator, leSource=addNodeDialog.node_logEntrySource, shape=addNodeDialog.node_type) self.qgv.build() self.nodeId += 1 #remove node button event def rem_node(): self.qgv.manipulation_mode = QGraphVizManipulationMode.Node_remove_Mode for btn in buttons_list: btn.setChecked(False) btnRemNode.setChecked(True) #remove edge button event def rem_edge(): self.qgv.manipulation_mode = QGraphVizManipulationMode.Edge_remove_Mode for btn in buttons_list: btn.setChecked(False) btnRemEdge.setChecked(True) #add edge button event def add_edge(): self.qgv.manipulation_mode = QGraphVizManipulationMode.Edges_Connect_Mode for btn in buttons_list: btn.setChecked(False) btnAddEdge.setChecked(True) self.newRelationshipFlag = True #updates json file with all graph properties (nodes & edges) def update_json(item): fname = "ui/windows/graph.json" self.qgv.saveAsJson(fname) addRelationshipToTable() #remove node from node table widget def removeNode(node): fname = "ui/windows/graph.json" self.qgv.saveAsJson(fname) self.row = getNodeRowNumber(self.tableWidgetNodes, node.name) self.tableWidgetNodes.removeRow(self.row) #remove relationship from relationship table widget def removeRelationship(edge): fname = "ui/windows/graph.json" self.qgv.saveAsJson(fname) self.row = getEdgeRowNumber(self.tableWidgetRelationships, edge.source.name, edge.dest.name) self.tableWidgetRelationships.removeRow(self.row) #return row number for given node def getNodeRowNumber(widget, nodeName): rowCount = widget.rowCount() for x in range(rowCount): node = widget.item(x, 2).text() if node == nodeName: return x #return row number for given edge def getEdgeRowNumber(widget, edgeSource, edgeDestination): rowCount = widget.rowCount() for x in range(rowCount): edgeSrc = widget.item(x, 2).text() edgeDest = widget.item(x, 3).text() if edgeSrc == edgeSource and edgeDest == edgeDestination: return x #add new relationship from graph onto relationship table def addRelationshipToTable(): with open('ui/windows/graph.json') as json_file: data = json.load(json_file) self.index = len(data['edges']) - 1 #new table widget item self.tableWidgetRelationships.insertRow(0) item = QtWidgets.QTableWidgetItem() item.setCheckState(QtCore.Qt.Unchecked) item.setFlags(QtCore.Qt.ItemIsDragEnabled | QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled) self.tableWidgetRelationships.setItem(0, 0, item) #write data on table widget in corresponding cells insert = QtCore.QCoreApplication.translate item = self.tableWidgetRelationships.item(0, 0) item.setText(insert("GraphWindow", str(self.relationshipId))) self.tableWidgetRelationships.setItem( 0, 2, QtWidgets.QTableWidgetItem( data["edges"][self.index]["source"])) self.tableWidgetRelationships.setItem( 0, 3, QtWidgets.QTableWidgetItem(data["edges"][self.index]["dest"])) self.relationshipId += 1 # Add two horizontal layouts (pannels to hold buttons) hpanelTop = QHBoxLayout() graphWidget.layout().addLayout(hpanelTop) hpanelBottom = QHBoxLayout() graphWidget.layout().addLayout(hpanelBottom) # Add buttons btnNew = QPushButton("New") btnNew.clicked.connect(new) hpanelTop.addWidget(btnNew) btnOpen = QPushButton("Open") btnOpen.clicked.connect(load) hpanelTop.addWidget(btnOpen) btnSave = QPushButton("Export") btnSave.clicked.connect(save) hpanelTop.addWidget(btnSave) buttons_list = [] btnManip = QPushButton("Manipulate") btnManip.setCheckable(True) btnManip.setChecked(True) btnManip.clicked.connect(manipulate) hpanelTop.addWidget(btnManip) buttons_list.append(btnManip) btnAddNode = QPushButton("Add Node") btnAddNode.clicked.connect(add_node) hpanelBottom.addWidget(btnAddNode) buttons_list.append(btnManip) btnRemNode = QPushButton("Rem Node") btnRemNode.setCheckable(True) btnRemNode.clicked.connect(rem_node) hpanelBottom.addWidget(btnRemNode) buttons_list.append(btnRemNode) btnAddEdge = QPushButton("Add Relationship") btnAddEdge.setCheckable(True) btnAddEdge.clicked.connect(add_edge) hpanelBottom.addWidget(btnAddEdge) buttons_list.append(btnAddEdge) btnRemEdge = QPushButton("Rem Relationship") btnRemEdge.setCheckable(True) btnRemEdge.clicked.connect(rem_edge) hpanelBottom.addWidget(btnRemEdge) buttons_list.append(btnRemEdge) #*-------------------------Tabular View Subwindow------------------------------------------------------------------*# self.subwindow_Table = QtWidgets.QWidget() self.subwindow_Table.setLayoutDirection(QtCore.Qt.RightToLeft) self.subwindow_Table.setObjectName("subwindow_Table") self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.subwindow_Table) self.verticalLayout_3.setObjectName("verticalLayout_3") #table widget self.tableWidgetNodes = QtWidgets.QTableWidget(self.subwindow_Table) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.tableWidgetNodes.sizePolicy().hasHeightForWidth()) self.tableWidgetNodes.setSizePolicy(sizePolicy) self.tableWidgetNodes.setLayoutDirection(QtCore.Qt.LeftToRight) self.tableWidgetNodes.setFrameShape(QtWidgets.QFrame.Box) self.tableWidgetNodes.setFrameShadow(QtWidgets.QFrame.Sunken) self.tableWidgetNodes.setAlternatingRowColors(True) self.tableWidgetNodes.setSelectionMode( QtWidgets.QAbstractItemView.MultiSelection) self.tableWidgetNodes.setSelectionBehavior( QtWidgets.QAbstractItemView.SelectItems) self.tableWidgetNodes.setTextElideMode(QtCore.Qt.ElideRight) self.tableWidgetNodes.setVerticalScrollMode( QtWidgets.QAbstractItemView.ScrollPerPixel) self.tableWidgetNodes.setHorizontalScrollMode( QtWidgets.QAbstractItemView.ScrollPerPixel) self.tableWidgetNodes.setShowGrid(False) self.tableWidgetNodes.setGridStyle(QtCore.Qt.SolidLine) self.tableWidgetNodes.setCornerButtonEnabled(False) #table properties self.tableWidgetNodes.horizontalHeader().setCascadingSectionResizes( False) self.tableWidgetNodes.horizontalHeader().setDefaultSectionSize(142) self.tableWidgetNodes.horizontalHeader().setHighlightSections(True) self.tableWidgetNodes.horizontalHeader().setSortIndicatorShown(True) self.tableWidgetNodes.horizontalHeader().setStretchLastSection(True) self.tableWidgetNodes.verticalHeader().setVisible(True) self.tableWidgetNodes.verticalHeader().setMinimumSectionSize(30) self.tableWidgetNodes.verticalHeader().setSortIndicatorShown(False) self.tableWidgetNodes.verticalHeader().setStretchLastSection(False) self.verticalLayout_3.addWidget(self.tableWidgetNodes) #*-------------------------Relationship Table Subwindow------------------------------------------------------------------*# #subwindow and layout properties self.subwindow_Relationship = QtWidgets.QWidget() self.subwindow_Relationship.setLayoutDirection(QtCore.Qt.RightToLeft) self.subwindow_Relationship.setObjectName("subwindow_Relationship") self.verticalLayout = QtWidgets.QVBoxLayout( self.subwindow_Relationship) self.verticalLayout.setContentsMargins(-1, -1, 17, -1) self.verticalLayout.setObjectName("verticalLayout") #add relationship frame self.frameRelationship = QtWidgets.QFrame(self.subwindow_Relationship) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.frameRelationship.sizePolicy().hasHeightForWidth()) self.frameRelationship.setSizePolicy(sizePolicy) self.frameRelationship.setLayoutDirection(QtCore.Qt.RightToLeft) self.frameRelationship.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frameRelationship.setFrameShadow(QtWidgets.QFrame.Raised) self.frameRelationship.setObjectName("frameRelationship") self.verticalLayout.addWidget(self.frameRelationship) self.gridLayout_2 = QtWidgets.QGridLayout(self.frameRelationship) self.gridLayout_2.setObjectName("gridLayout_2") #relationship label & line edit self.labelRelationship = QtWidgets.QLabel(self.frameRelationship) self.labelRelationship.setObjectName("labelRelationship") self.gridLayout_2.addWidget(self.labelRelationship, 0, 2, 1, 1) self.lineEditRelationship = QtWidgets.QLineEdit(self.frameRelationship) self.lineEditRelationship.setObjectName("lineEditRelationship") self.gridLayout_2.addWidget(self.lineEditRelationship, 0, 1, 1, 1) #parent node label & line edit self.labelParent = QtWidgets.QLabel(self.frameRelationship) self.labelParent.setObjectName("labelParent") self.gridLayout_2.addWidget(self.labelParent, 1, 2, 1, 1) self.lineEditParent = QtWidgets.QLineEdit(self.frameRelationship) self.lineEditParent.setObjectName("lineEditParent") self.gridLayout_2.addWidget(self.lineEditParent, 1, 1, 1, 1) #child node label & line edit self.labelChild = QtWidgets.QLabel(self.frameRelationship) self.labelChild.setObjectName("labelChild") self.gridLayout_2.addWidget(self.labelChild, 2, 2, 1, 1) self.lineEditChild = QtWidgets.QLineEdit(self.frameRelationship) self.lineEditChild.setObjectName("lineEditChild") self.gridLayout_2.addWidget(self.lineEditChild, 2, 1, 1, 1) #add relationship button self.pushButtonAddRelationship = QtWidgets.QPushButton( self.frameRelationship) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.pushButtonAddRelationship.sizePolicy().hasHeightForWidth()) self.pushButtonAddRelationship.setSizePolicy(sizePolicy) self.pushButtonAddRelationship.setObjectName( "pushButtonAddRelationship") self.gridLayout_2.addWidget(self.pushButtonAddRelationship, 3, 1, 1, 1) #relationships table self.tableWidgetRelationships = QtWidgets.QTableWidget( self.subwindow_Relationship) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.tableWidgetRelationships.sizePolicy().hasHeightForWidth()) self.tableWidgetRelationships.setSizePolicy(sizePolicy) self.tableWidgetRelationships.setLayoutDirection(QtCore.Qt.LeftToRight) self.tableWidgetRelationships.setAlternatingRowColors(True) self.tableWidgetRelationships.setVerticalScrollMode( QtWidgets.QAbstractItemView.ScrollPerPixel) self.tableWidgetRelationships.setHorizontalScrollMode( QtWidgets.QAbstractItemView.ScrollPerPixel) self.tableWidgetRelationships.setShowGrid(False) self.tableWidgetRelationships.setObjectName("tableWidgetRelationships") self.tableWidgetRelationships.setSelectionMode( QtWidgets.QAbstractItemView.MultiSelection) # a relationship is the length of a single relationship relationship = 4 # relationships is the length of a set of relationships relationships = 0 # setting the relationship table dimensions self.tableWidgetRelationships.setColumnCount(relationship) self.tableWidgetRelationships.setRowCount(relationships) # creating the row header for relationships for relation in range(relationship): item = QtWidgets.QTableWidgetItem() item.setTextAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignVCenter) self.tableWidgetRelationships.setHorizontalHeaderItem( relation, item) for relation in range(relationships): item = QtWidgets.QTableWidgetItem() self.tableWidgetRelationships.setVerticalHeaderItem(relation, item) # creates the table for relation in range(relationships): # creates a checkbox in the column item = QtWidgets.QTableWidgetItem() item.setCheckState(QtCore.Qt.Unchecked) self.tableWidgetRelationships.setItem(relation, 0, item) for label in range(relationship): item = QtWidgets.QTableWidgetItem() self.tableWidgetRelationships.setItem(relation, label + 1, item) self.tableWidgetRelationships.horizontalHeader().setVisible(True) self.tableWidgetRelationships.horizontalHeader().setMinimumSectionSize( 39) self.tableWidgetRelationships.horizontalHeader().setSortIndicatorShown( True) self.tableWidgetRelationships.horizontalHeader().setStretchLastSection( True) self.tableWidgetRelationships.verticalHeader().setVisible(True) self.tableWidgetRelationships.verticalHeader().setDefaultSectionSize( 30) self.tableWidgetRelationships.verticalHeader().setSortIndicatorShown( False) self.verticalLayout.addWidget(self.tableWidgetRelationships) self.mdiArea.addSubWindow(self.subwindow_Relationship) self.mdiArea.addSubWindow(self.subwindow_Table) self.gridLayout.addWidget(self.mdiArea, 1, 0, 1, 1) self.graphSubWin = self.mdiArea.addSubWindow(self.subwindow_Graph) #*------------------------------Menu Bar---------------------------------------------------*# graphWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(graphWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 1155, 21)) self.menubar.setObjectName("menubar") self.menuFile = QtWidgets.QMenu(self.menubar) self.menuFile.setObjectName("menuFile") self.menuOpen_Window = QtWidgets.QMenu(self.menuFile) self.menuOpen_Window.setObjectName("menuOpen_Window") self.menuSubwindow_Layout_2 = QtWidgets.QMenu(self.menuFile) self.menuSubwindow_Layout_2.setObjectName("menuSubwindow_Layout_2") self.menuMenu = QtWidgets.QMenu(self.menubar) self.menuMenu.setObjectName("menuMenu") graphWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(graphWindow) self.statusbar.setObjectName("statusbar") graphWindow.setStatusBar(self.statusbar) self.actionEvent_Configuration = QtWidgets.QAction(graphWindow) self.actionEvent_Configuration.setObjectName( "actionEvent_Configuration") self.actionEnforcement_Action_Report = QtWidgets.QAction(graphWindow) self.actionEnforcement_Action_Report.setObjectName( "actionEnforcement_Action_Report") self.actionManage_Graph = QtWidgets.QAction(graphWindow) self.actionManage_Graph.setObjectName("actionManage_Graph") self.actionFilter_Logs = QtWidgets.QAction(graphWindow) self.actionFilter_Logs.setObjectName("actionFilter_Logs") self.actionGraphical_View = QtWidgets.QAction(graphWindow) self.actionGraphical_View.setObjectName("actionGraphical_View") self.actionTabular_View = QtWidgets.QAction(graphWindow) self.actionTabular_View.setObjectName("actionTabular_View") self.actionRelationship_Table = QtWidgets.QAction(graphWindow) self.actionRelationship_Table.setObjectName("actionRelationship_Table") self.actionTile = QtWidgets.QAction(graphWindow) self.actionTile.setObjectName("actionTile") self.actionCascade = QtWidgets.QAction(graphWindow) self.actionCascade.setObjectName("actionCascade") self.actionCascade.triggered.connect(self.mdiArea.cascadeSubWindows) self.menuOpen_Window.addAction(self.actionGraphical_View) self.menuOpen_Window.addAction(self.actionTabular_View) self.menuOpen_Window.addAction(self.actionRelationship_Table) self.menuSubwindow_Layout_2.addAction(self.actionTile) self.menuSubwindow_Layout_2.addAction(self.actionCascade) self.menuFile.addAction(self.menuOpen_Window.menuAction()) self.menuFile.addAction(self.menuSubwindow_Layout_2.menuAction()) self.menuMenu.addAction(self.actionEvent_Configuration) self.menuMenu.addAction(self.actionEnforcement_Action_Report) self.menuMenu.addAction(self.actionManage_Graph) self.menuMenu.addAction(self.actionFilter_Logs) self.menubar.addAction(self.menuMenu.menuAction()) self.menubar.addAction(self.menuFile.menuAction()) self.mdiArea.tileSubWindows() self.retranslateUi(graphWindow) self.actionTile.triggered.connect(self.mdiArea.tileSubWindows) QtCore.QMetaObject.connectSlotsByName(graphWindow)
def update_graph(self, vector): """creates initial empty graph and reads node and relationship tables every time there is a change creates graphical elements for all nodes and edges""" show_subgraphs = True qgv = self.qgv show_subgraphs = True qgv.setStyleSheet("background-color:white;") # Create A new Graph using Dot layout engine qgv.new(Dot(Graph("Main_Graph"), show_subgraphs=show_subgraphs)) vector_name = vector.name # destroys previous graph so it can be populated by the new elements if ((self.layout_u.count()) > 0): while self.layout_u.count(): child = self.layout_u.takeAt(0) if child.widget(): child.widget().deleteLater() node_dict = {} # reads node info and creates graphical nodes for i in range(len(vector.get_nodes())): if vector.get_nodes()[i].is_visible(): node_name = (vector.get_nodes()[i].get_name()) node_type = (vector.get_nodes()[i].get_log_creator()) if node_type == 'red' or node_type == 'blue' or node_type == "white": color = node_type else: color = "grey" node_dict[str( vector.get_nodes()[i].get_id())] = self.qgv.addNode( qgv.engine.graph, node_name, label=node_name, fillcolor=color) # n.append(self.qgv.addNode(qgv.engine.graph, node_name, label=node_name, fillcolor=color)) # reads relationship information and creates lines between nodes for i in range(len(vector.get_relationships())): if vector.get_relationships()[i].parent.is_visible( ) and vector.get_relationships()[i].child.is_visible(): # parent_node = n[int(vector.get_relationships()[i].get_parent_id())-1] # child_node = n[int(vector.get_relationships()[i].get_child_id())-1] parent_node = node_dict[str( vector.get_relationships()[i].get_parent_id())] child_node = node_dict[str( vector.get_relationships()[i].get_child_id())] self.qgv.addEdge(parent_node, child_node, {}) # builds new graph, saves it in a qgv file, and loads it back onto the widget qgv.build() for i in range(len(vector.get_nodes())): if vector.get_nodes()[i].x != 0 and vector.get_nodes( )[i].is_visible(): node_dict[vector.get_nodes() [i].get_id()].pos[0] = vector.get_nodes()[i].x node_dict[vector.get_nodes() [i].get_id()].pos[1] = vector.get_nodes()[i].y qgv.save("./gv/" + vector_name + ".gv") self.layout_u.addWidget(qgv) self.qgv = qgv
def new(): qgv.engine.graph = Graph("MainGraph") qgv.build() qgv.repaint()
def __init__(self): super(MainWindow, self).__init__() loadUi('../ui/MainWindow.ui', self) self.FilterConfigButton = self.findChild(QPushButton, 'filterButton') self.FilterConfigButton.clicked.connect(self.openFilterConfig) self.settingsConfig = self.findChild(QAction, 'actionSettings') self.settingsConfig.triggered.connect(self.openSettings) #Search button functionality ##need to add keyword search still self.searchSearchButton = self.findChild(QPushButton, 'searchSearchButton') self.searchSearchButton.clicked.connect(self.openFilterConfig) # Enter press on qlineedit search tab triggers the search button self.searchLineEdit = self.findChild(QLineEdit, 'lineEdit_2') self.searchLineEdit.returnPressed.connect( self.searchSearchButton.click) #Search button on graph tab functionality ##need keyword functionality added self.graphSearchButton = self.findChild(QPushButton, 'graphSearchButton_2') # Enter press on qlineedit graph tab triggers search button self.graphSearchEdit = self.findChild(QLineEdit, 'graphLineEdit') self.graphSearchEdit.returnPressed.connect( self.graphSearchButton.click) #Exit menu option functionality self.CloseMenuSelect = self.findChild(QAction, 'actionClose_Exit') self.CloseMenuSelect.setShortcut('Ctrl+Q') self.CloseMenuSelect.triggered.connect(qApp.quit) #Export menu option functionality self.exportConfig = self.findChild(QAction, 'actionExport') self.exportConfig.setShortcut('Ctrl+E') self.exportConfig.triggered.connect(self.openExportConfig) #VectorDBConfig linked to menu option self.versionControl = self.findChild(QAction, 'actionVersion_Control') self.versionControl.setShortcut('Ctrl+S') self.versionControl.triggered.connect(self.openVectDBConfig) self.actionLogFile = self.findChild(QAction, 'actionFileConfig') self.actionLogFile.setShortcut('Ctrl+F') self.actionLogFile.triggered.connect(self.openLogConfig) self.GraphTable = self.findChild(QTableWidget, 'tableWidget') self.graphArea = self.findChild(QWidget, 'graphArea') self.graphArea.setLayout(QVBoxLayout()) self.GraphTable.setItem(0, 0, QTableWidgetItem("Cell (1,1)")) # Events def node_selected(node): if qgv.manipulation_mode == QGraphVizManipulationMode.Node_remove_Mode: print("Node {} removed".format(node)) else: print("Node selected {}".format(node)) def edge_selected(edge): if qgv.manipulation_mode == QGraphVizManipulationMode.Edge_remove_Mode: print("Edge {} removed".format(edge)) else: print("Edge selected {}".format(edge)) def node_invoked(node): print("Node double clicked") def edge_invoked(node): print("Edge double clicked") def node_removed(node): print("Node removed") def edge_removed(node): print("Edge removed") # Create QGraphViz widget show_subgraphs = True qgv = QGraphViz(show_subgraphs=show_subgraphs, node_selected_callback=node_selected, edge_selected_callback=edge_selected, node_invoked_callback=node_invoked, edge_invoked_callback=edge_invoked, node_removed_callback=node_removed, edge_removed_callback=edge_removed, hilight_Nodes=True, hilight_Edges=True) qgv.setStyleSheet("background-color:white;") # Create A new Graph using Dot layout engine qgv.new(Dot(Graph("Main_Graph"), show_subgraphs=show_subgraphs)) # Adding nodes with an image as its shape icon_path = os.path.dirname(os.path.abspath(__file__)) + r"\dbicon.png" # Build the graph (the layout engine organizes where the nodes and connections are) qgv.build() # Save it to a file to be loaded by Graphviz if needed qgv.save("test.gv") # Add the QGraphViz object to the layout self.graphArea.layout().addWidget(qgv) # Add a horizontal layout (a pannel to select what to do) hpanel = QHBoxLayout() self.graphArea.layout().addLayout(hpanel) # Add few buttons to the panel def manipulate(): qgv.manipulation_mode = QGraphVizManipulationMode.Nodes_Move_Mode def save(): fname = QFileDialog.getSaveFileName(qgv, "Save", "", "*.json") if (fname[0] != ""): qgv.saveAsJson(fname[0]) def new(): qgv.engine.graph = Graph("MainGraph") qgv.build() qgv.repaint() def load(): fname = QFileDialog.getOpenFileName(qgv, "Open", "", "*.json") if (fname[0] != ""): qgv.loadAJson(fname[0]) def add_node(): dlg = QDialog() dlg.ok = False dlg.node_name = "" dlg.node_label = "" dlg.node_type = "None" # Layouts main_layout = QVBoxLayout() l = QFormLayout() buttons_layout = QHBoxLayout() main_layout.addLayout(l) main_layout.addLayout(buttons_layout) dlg.setLayout(main_layout) leNodeName = QLineEdit() leNodeLabel = QLineEdit() cbxNodeType = QComboBox() leImagePath = QLineEdit() pbOK = QPushButton() pbCancel = QPushButton() cbxNodeType.addItems(["None", "circle", "box"]) pbOK.setText("&OK") pbCancel.setText("&Cancel") l.setWidget(0, QFormLayout.LabelRole, QLabel("Node Name")) l.setWidget(0, QFormLayout.FieldRole, leNodeName) l.setWidget(1, QFormLayout.LabelRole, QLabel("Node Label")) l.setWidget(1, QFormLayout.FieldRole, leNodeLabel) l.setWidget(2, QFormLayout.LabelRole, QLabel("Node Type")) l.setWidget(2, QFormLayout.FieldRole, cbxNodeType) l.setWidget(3, QFormLayout.LabelRole, QLabel("Node Image")) l.setWidget(3, QFormLayout.FieldRole, leImagePath) def ok(): dlg.OK = True dlg.node_name = leNodeName.text() dlg.node_label = leNodeLabel.text() if (leImagePath.text()): dlg.node_type = leImagePath.text() else: dlg.node_type = cbxNodeType.currentText() dlg.close() def cancel(): dlg.OK = False dlg.close() pbOK.clicked.connect(ok) pbCancel.clicked.connect(cancel) buttons_layout.addWidget(pbOK) buttons_layout.addWidget(pbCancel) dlg.exec_() # node_name, okPressed = QInputDialog.getText(wi, "Node name","Node name:", QLineEdit.Normal, "") if dlg.OK and dlg.node_name != '': qgv.addNode(qgv.engine.graph, dlg.node_name, label=dlg.node_label, shape=dlg.node_type) qgv.build() def add_node(node_id, node_name, node_timestamp, node_description, log_entry_reference, log_creator, event_type, icon_type, source, visibility): qgv.addNode(qgv.engine.graph, node_name, label=node_description, shape='icons/blue_circle.png') def remove_node(): qgv.manipulation_mode = QGraphVizManipulationMode.Node_remove_Mode for btn in buttons_list: btn.setChecked(False) btnRemoveNode.setChecked(True) def remove_edge(): qgv.manipulation_mode = QGraphVizManipulationMode.Edge_remove_Mode for btn in buttons_list: btn.setChecked(False) btnRemoveEdge.setChecked(True) def add_edge(): qgv.manipulation_mode = QGraphVizManipulationMode.Edges_Connect_Mode for btn in buttons_list: btn.setChecked(False) btnAddEdge.setChecked(True) # Add buttons btnNew = QPushButton("New") btnNew.clicked.connect(new) btnOpen = QPushButton("Open") btnOpen.clicked.connect(load) btnSave = QPushButton("Save") btnSave.clicked.connect(save) hpanel.addWidget(btnNew) hpanel.addWidget(btnOpen) hpanel.addWidget(btnSave) buttons_list = [] btnManip = QPushButton("Manipulate") btnManip.setCheckable(True) btnManip.setChecked(True) btnManip.clicked.connect(manipulate) hpanel.addWidget(btnManip) buttons_list.append(btnManip) btnAddNode = QPushButton("Add Node") btnAddNode.clicked.connect(add_node) hpanel.addWidget(btnAddNode) buttons_list.append(btnAddNode) btnRemoveNode = QPushButton("Remove Node") btnRemoveNode.setCheckable(True) btnRemoveNode.clicked.connect(remove_node) hpanel.addWidget(btnRemoveNode) buttons_list.append(btnRemoveNode) btnAddEdge = QPushButton("Add Edge") btnAddEdge.setCheckable(True) btnAddEdge.clicked.connect(add_edge) hpanel.addWidget(btnAddEdge) buttons_list.append(btnAddEdge) btnRemoveEdge = QPushButton("Remove Edge") btnRemoveEdge.setCheckable(True) btnRemoveEdge.clicked.connect(remove_edge) hpanel.addWidget(btnRemoveEdge) buttons_list.append(btnRemoveEdge) #drop down menus vector collumn search table self.searchSearchTableWidget = self.findChild(QTableWidget, 'tableWidget_2') i = 0 while i < 10: combo = QComboBox() combo.addItems([' ', '1', '2', '3']) self.searchSearchTableWidget.setCellWidget(i, 3, combo) i += 1 self.showMaximized()
qgv = QGraphViz( show_subgraphs=show_subgraphs, node_selected_callback=node_selected, edge_selected_callback=edge_selected, node_invoked_callback=node_invoked, edge_invoked_callback=edge_invoked, node_removed_callback=node_removed, edge_removed_callback=edge_removed, hilight_Nodes=True, hilight_Edges=True ) qgv.setStyleSheet("background-color:white;") # Create A new Graph using Dot layout engine qgv.new(Dot(Graph("Main_Graph"), show_subgraphs=show_subgraphs)) # Adding nodes with an image as its shape icon_path = os.path.dirname(os.path.abspath(__file__)) + r"\dbicon.png" # Build the graph (the layout engine organizes where the nodes and connections are) qgv.build() # Save it to a file to be loaded by Graphviz if needed qgv.save("test.gv") # Create a Main window w = QMainWindow() w.setWindowTitle('Graph') # Create a central widget to handle the QGraphViz object wi = QWidget() wi.setLayout(QVBoxLayout()) w.setCentralWidget(wi)
def setup(self): self.qgv.new(Dot(Graph(self.name)))
def __init__(self): super(MainWindow, self).__init__() loadUi('../ui/MainWindow.ui', self) self.myDb = DBHandler() self.updateTableFlag = True self.FilterConfigButton = self.findChild(QPushButton, 'filterButton') self.FilterConfigButton.clicked.connect(self.openFilterConfig) self.settingsConfig = self.findChild(QAction, 'actionSettings') self.settingsConfig.triggered.connect(self.openSettings) #Search button functionality ##need to add keyword search still self.searchSearchButton = self.findChild(QPushButton, 'searchSearchButton') self.searchSearchButton.clicked.connect(self.openFilterConfig) # Enter press on qlineedit search tab triggers the search button self.searchLineEdit = self.findChild(QLineEdit, 'lineEdit_2') self.searchLineEdit.returnPressed.connect( self.searchSearchButton.click) # Enter press on qlineedit graph tab triggers search button self.graphSearchEdit = self.findChild(QLineEdit, 'graphLineEdit') #Exit menu option functionality self.CloseMenuSelect = self.findChild(QAction, 'actionClose_Exit') self.CloseMenuSelect.setShortcut('Ctrl+Q') self.CloseMenuSelect.triggered.connect(qApp.quit) #Export menu option functionality self.exportConfig = self.findChild(QAction, 'actionExport') self.exportConfig.setShortcut('Ctrl+E') self.exportConfig.triggered.connect(self.openExportConfig) #VectorDBConfig linked to menu option self.versionControl = self.findChild(QAction, 'actionVersion_Control') self.versionControl.setShortcut('Ctrl+S') self.versionControl.triggered.connect(self.openVectDBConfig) self.GraphTable = self.findChild(QTableWidget, 'tableWidget') self.graphArea = self.findChild(QWidget, 'graphArea') self.graphArea.setLayout(QVBoxLayout()) self.graphSearchButton = self.findChild(QPushButton, 'graphSearchButton_2') # self.graphSearchButton.clicked.connect() self.currentVectorMenu = self.findChild(QComboBox, 'VectorMenu') self.currentVectorLabel = self.findChild(QLabel, 'CurrentVector') self.currentVectorMenu.addItems(self.myDb.get_vector_names()) self.currentVectorLabel.setText(self.currentVectorMenu.currentText()) self.currentVectorMenu.activated.connect(self.vectorSelected) self.GraphTable.cellClicked.connect(self.entryFieldSelected) self.GraphTable.cellChanged.connect(self.updateEntryFromTable) # Events def node_selected(node): if self.qgv.manipulation_mode == QGraphVizManipulationMode.Node_remove_Mode: print("Node {} removed".format(node)) self.saveGraph() # self.updateTableFromGraph() else: print("Node selected {}".format(node)) def edge_selected(edge): if self.qgv.manipulation_mode == QGraphVizManipulationMode.Edge_remove_Mode: print("Edge {} removed".format(edge)) else: print("Edge selected {}".format(edge)) def node_invoked(node): print("Node double clicked") def edge_invoked(node): print("Edge double clicked") def node_removed(node): print("Node removed") def edge_removed(node): print("Edge removed") # Create QGraphViz widget show_subgraphs = True self.qgv = QGraphViz(show_subgraphs=show_subgraphs, node_selected_callback=node_selected, edge_selected_callback=edge_selected, node_invoked_callback=node_invoked, edge_invoked_callback=edge_invoked, node_removed_callback=node_removed, edge_removed_callback=edge_removed, hilight_Nodes=True, hilight_Edges=True) self.qgv.setStyleSheet("background-color:white;") # Create A new Graph using Dot layout engine self.qgv.new(Dot(Graph("Main_Graph"), show_subgraphs=show_subgraphs)) # Adding nodes with an image as its shape icon_path = os.path.dirname(os.path.abspath(__file__)) + r"\dbicon.png" # Build the graph (the layout engine organizes where the nodes and connections are) self.qgv.build() # Save it to a file to be loaded by Graphviz if needed self.qgv.save("test.gv") # Add the QGraphViz object to the layout self.graphArea.layout().addWidget(self.qgv) # Add a horizontal layout (a pannel to select what to do) self.hpanel = QHBoxLayout() self.graphArea.layout().addLayout(self.hpanel) # Add buttons to the panel def save(): fname = QFileDialog.getSaveFileName(self.qgv, "Save", "", "*.json") if (fname[0] != ""): self.qgv.saveAsJson(fname[0]) def new(): self.qgv.engine.graph = Graph("MainGraph") self.qgv.build() self.qgv.repaint() def load(): fname = QFileDialog.getOpenFileName(self.qgv, "Open", "", "*.json") if (fname[0] != ""): self.qgv.loadAJson(fname[0]) def add_node(): dlg = QDialog() dlg.ok = False dlg.node_name = "" dlg.node_label = "" dlg.node_color = "" dlg.node_type = "None" # Layouts main_layout = QVBoxLayout() l = QFormLayout() buttons_layout = QHBoxLayout() main_layout.addLayout(l) main_layout.addLayout(buttons_layout) dlg.setLayout(main_layout) leNodeName = QLineEdit() leNodeLabel = QLineEdit() cbxNodeType = QComboBox() leImagePath = QLineEdit() leNodeColor = QLineEdit() pbOK = QPushButton() pbCancel = QPushButton() cbxNodeType.addItems(["None", "circle", "box"]) pbOK.setText("&OK") pbCancel.setText("&Cancel") l.setWidget(0, QFormLayout.LabelRole, QLabel("Node Name")) l.setWidget(0, QFormLayout.FieldRole, leNodeName) l.setWidget(1, QFormLayout.LabelRole, QLabel("Node Label")) l.setWidget(1, QFormLayout.FieldRole, leNodeLabel) l.setWidget(2, QFormLayout.LabelRole, QLabel("Node Type")) l.setWidget(2, QFormLayout.FieldRole, cbxNodeType) l.setWidget(3, QFormLayout.LabelRole, QLabel("Node Image")) l.setWidget(3, QFormLayout.FieldRole, leImagePath) l.setWidget(4, QFormLayout.LabelRole, QLabel("Node Color")) l.setWidget(4, QFormLayout.FieldRole, leNodeColor) def ok(): dlg.OK = True dlg.node_name = leNodeName.text() dlg.node_label = leNodeLabel.text() if (leImagePath.text()): dlg.node_type = leImagePath.text() else: dlg.node_type = cbxNodeType.currentText() dlg.node_color = leNodeColor.text() dlg.close() def cancel(): dlg.OK = False dlg.close() pbOK.clicked.connect(ok) pbCancel.clicked.connect(cancel) buttons_layout.addWidget(pbOK) buttons_layout.addWidget(pbCancel) dlg.exec_() # node_name, okPressed = QInputDialog.getText(wi, "Node name","Node name:", QLineEdit.Normal, "") if dlg.OK and dlg.node_name != '': self.qgv.addNode(self.qgv.engine.graph, dlg.node_name, label=dlg.node_label, shape=dlg.node_type, color=dlg.node_color) self.qgv.build() def remove_node(): self.qgv.manipulation_mode = QGraphVizManipulationMode.Node_remove_Mode for btn in self.buttons_list: btn.setChecked(False) self.btnRemoveNode.setChecked(True) def remove_edge(): self.qgv.manipulation_mode = QGraphVizManipulationMode.Edge_remove_Mode for btn in self.buttons_list: btn.setChecked(False) self.btnRemoveEdge.setChecked(True) def add_edge(): self.qgv.manipulation_mode = QGraphVizManipulationMode.Edges_Connect_Mode for btn in self.buttons_list: btn.setChecked(False) self.btnAddEdge.setChecked(True) # Add buttons self.btnNew = QPushButton("New") self.btnNew.clicked.connect(new) self.btnOpen = QPushButton("Open") self.btnOpen.clicked.connect(load) self.btnSave = QPushButton("Save") self.btnSave.clicked.connect(save) self.hpanel.addWidget(self.btnNew) self.hpanel.addWidget(self.btnOpen) self.hpanel.addWidget(self.btnSave) self.buttons_list = [] self.btnAddNode = QPushButton("Add Node") self.btnAddNode.clicked.connect(add_node) self.hpanel.addWidget(self.btnAddNode) self.buttons_list.append(self.btnAddNode) self.btnRemoveNode = QPushButton("Remove Node") self.btnRemoveNode.setCheckable(True) self.btnRemoveNode.clicked.connect(remove_node) self.hpanel.addWidget(self.btnRemoveNode) self.buttons_list.append(self.btnRemoveNode) self.btnAddEdge = QPushButton("Add Edge") self.btnAddEdge.setCheckable(True) self.btnAddEdge.clicked.connect(add_edge) self.hpanel.addWidget(self.btnAddEdge) self.buttons_list.append(self.btnAddEdge) self.btnRemoveEdge = QPushButton("Remove Edge") self.btnRemoveEdge.setCheckable(True) self.btnRemoveEdge.clicked.connect(remove_edge) self.hpanel.addWidget(self.btnRemoveEdge) self.buttons_list.append(self.btnRemoveEdge) #icon_path = os.path.dirname(os.path.abspath(__file__)) + r"\Resouces\IconDir,100,100" # n9 = qgv.addNode(qgv.engine.graph, "Node9", label="N9", shape=icon_path) #drop down menus vector collumn search table self.SearchTable = self.findChild(QTableWidget, 'tableWidget_2') self.showMaximized() # DBHandler.create_vector_entry('../Resources/LocalGraphs/VECTOR_3.json') self.updateViews()
def new(): self.qgv.engine.graph = Graph("MainGraph") self.qgv.build() self.qgv.repaint()
show_subgraphs = True qgv = QGraphViz( show_subgraphs=show_subgraphs, auto_freeze=True, # show autofreeze capability node_selected_callback=node_selected, edge_selected_callback=edge_selected, node_invoked_callback=node_invoked, edge_invoked_callback=edge_invoked, node_removed_callback=node_removed, edge_removed_callback=edge_removed, hilight_Nodes=True, hilight_Edges=True) qgv.setStyleSheet("background-color:white;") # Create A new Graph using Dot layout engine qgv.new( Dot(Graph("Main_Graph"), show_subgraphs=show_subgraphs, font=QFont("Arial", 12), margins=[20, 20])) # Define sone graph n1 = qgv.addNode(qgv.engine.graph, "Node1", label="N1", fillcolor="red") n2 = qgv.addNode(qgv.engine.graph, "Node2", label="N2", fillcolor="blue:white:red") n3 = qgv.addNode(qgv.engine.graph, "Node3", label="N3", shape="diamond", fillcolor="orange") n4 = qgv.addNode(qgv.engine.graph,
def read_vector_table(self, vector, qgv): if (vector == None): show_subgraphs = True qgv.setStyleSheet("background-color:white;") # Create A new Graph using Dot layout engine qgv.new(Dot(Graph("Main_Graph"), show_subgraphs=show_subgraphs)) # Define some graph n1 = qgv.addNode(qgv.engine.graph, "Node1", label="N1979", fillcolor="red") n2 = qgv.addNode(qgv.engine.graph, "Node2", label="N1969", fillcolor="blue") n3 = qgv.addNode(qgv.engine.graph, "Node3", label="N1954") n4 = qgv.addNode(qgv.engine.graph, "Node4", label="N1974") n5 = qgv.addNode(qgv.engine.graph, "Node5", label="N1964") n6 = qgv.addNode(qgv.engine.graph, "Node6", label="N1959", fillcolor="red") # sub = qgv.addSubgraph(qgv.engine.graph, "sub graph", qgv.engine.graph.graph_type, label="Subgraph", fillcolor="blue:white:red") # n7 = qgv.addNode(sub, "Node7", label="N7") # n8 = qgv.addNode(sub, "Node8", label="N8") # Adding nodes with an image as its shape icon_path = os.path.dirname( os.path.abspath(__file__)) + r"\icon\dbicon.png" #n9 = qgv.addNode(qgv.engine.graph, "Node9", label="N9", shape=icon_path) qgv.addEdge(n1, n2, {}) qgv.addEdge(n3, n2, {}) qgv.addEdge(n2, n4, {"width": 2}) qgv.addEdge(n4, n5, {"width": 4}) qgv.addEdge(n4, n6, {"width": 5}) qgv.addEdge(n3, n6, {"width": 2}) #qgv.addEdge(n6, n9, {"width":5,"color":"red"}) # Build the graph (the layout engine organizes where the nodes and connections are) qgv.build() # Save it to a file to be loaded by Graphviz if needed qgv.save("test.gv") # Add the QGraphViz object to the layout self.layout_u.addWidget(qgv) else: show_subgraphs = True qgv.setStyleSheet("background-color:white;") # Create A new Graph using Dot layout engine vector_name = vector.name qgv.new(Dot(Graph("Main_Graph"), show_subgraphs=show_subgraphs)) #adding nodes to graph '''if((self.layout_u.count())>0): while self.layout_u.count(): child = self.layout_u.takeAt(0) if child.widget() : child.widget().deleteLater()''' for i in range(len(vector.get_nodes())): node_name = (vector.get_nodes()[i].get_name()) node_type = (vector.get_nodes()[i].get_log_creator()) print("adding node") n = qgv.addNode(qgv.engine.graph, node_name, label=node_name, fillcolor=node_type) # Build the graph (the layout engine organizes where the nodes and connections are) qgv.build() # Save it to a file to be loaded by Graphviz if needed file_name = (vector_name + ".gv") qgv.save(file_name)
def initUI(self): self.setGeometry(200, 200, 800, 600) self.layout = QHBoxLayout() self.layout.setContentsMargins(0, 0, 0, 0) self.setLayout(self.layout) # Create graphics scene # Creating the tablular view self.table = QTableWidget(0, 10, self) # self.table.setFixedWidth(850) self.table.setHorizontalHeaderItem(0, QTableWidgetItem(QIcon('icons/up_arrow.png'), "Node ID")) self.table.setHorizontalHeaderItem(1, QTableWidgetItem(QIcon('icons/up_arrow.png'), "Node Name")) self.table.setHorizontalHeaderItem(2, QTableWidgetItem(QIcon('icons/up_arrow.png'), "Node Timestamp")) self.table.setHorizontalHeaderItem(3, QTableWidgetItem(QIcon('icons/up_arrow.png'), "Node Description")) self.table.setHorizontalHeaderItem(4, QTableWidgetItem(QIcon('icons/up_arrow.png'), "Log Entry Reference")) self.table.setHorizontalHeaderItem(5, QTableWidgetItem(QIcon('icons/up_arrow.png'), 'Log Creator')) self.table.setHorizontalHeaderItem(6, QTableWidgetItem('Event Type')) self.table.setHorizontalHeaderItem(7, QTableWidgetItem(QIcon('icon/unchecked.png'), "Icon Type")) self.table.setHorizontalHeaderItem(8, QTableWidgetItem(QIcon('icons/up_arrow.png'), 'Source')) self.table.setHorizontalHeaderItem(9, QTableWidgetItem('Node Visibility')) self.header = self.table.horizontalHeader() for i in range(self.table.columnCount()): self.header.setSectionResizeMode(i, QHeaderView.ResizeToContents) # Creating the Graphical View self.layout.addWidget(self.table, 1) self.setWindowTitle('Node Editor') # Events def node_selected(node): if self.qgv.manipulation_mode == QGraphVizManipulationMode.Node_remove_Mode: print("Node {} removed".format(node)) if self.qgv.manipulation_mode == QGraphVizManipulationMode.Nodes_Move_Mode: pass else: print("Node selected {}".format(node)) def edge_selected(edge): if self.qgv.manipulation_mode == QGraphVizManipulationMode.Edge_remove_Mode: print("Edge {} removed".format(edge)) else: print("Edge selected {}".format(edge)) def node_invoked(node): print("Node double clicked") def edge_invoked(node): print("Edge double clicked") def node_removed(node): print("Node removed") def edge_removed(node): print("Edge removed") # Create QGraphViz widget show_subgraphs = True self.qgv = QGraphViz( show_subgraphs=show_subgraphs, node_selected_callback=node_selected, edge_selected_callback=edge_selected, node_invoked_callback=node_invoked, edge_invoked_callback=edge_invoked, node_removed_callback=node_removed, edge_removed_callback=edge_removed, hilight_Nodes=True, hilight_Edges=True ) self.qgv.setStyleSheet("background-color:white;") # Create A new Graph using Dot layout engine self.qgv.new(Dot(Graph("Main_Graph"), show_subgraphs=show_subgraphs)) # Adding nodes with an image as its shape icon_path = os.path.dirname(os.path.abspath(__file__)) + r"\dbicon.png" # Build the graph (the layout engine organizes where the nodes and connections are) self.qgv.build() # Save it to a file to be loaded by Graphviz if needed self.qgv.save("test.gv") self.graphArea = QWidget() # Add the QGraphViz object to the layout self.graphArea.setLayout(QVBoxLayout()) self.graphArea.layout().addWidget(self.qgv) # Add a horizontal layout (a pannel to select what to do) hpanel = QHBoxLayout() self.graphArea.layout().addLayout(hpanel) self.layout.addWidget(self.graphArea) # Add few buttons to the panel def manipulate(): self.qgv.manipulation_mode = QGraphVizManipulationMode.Nodes_Move_Mode def save(): fname = QFileDialog.getSaveFileName(self.qgv, "Save", "", "*.json") if (fname[0] != ""): self.qgv.saveAsJson(fname[0]) def new(): self.qgv.engine.graph = Graph("MainGraph") self.qgv.build() self.qgv.repaint() def load(): fname = QFileDialog.getOpenFileName(self.qgv, "Open", "", "*.json") if (fname[0] != ""): self.qgv.loadAJson(fname[0]) def add_node(): dlg = QDialog() dlg.ok = False dlg.node_name = "" dlg.node_label = "" dlg.node_type = "None" # Layouts main_layout = QVBoxLayout() l = QFormLayout() buttons_layout = QHBoxLayout() main_layout.addLayout(l) main_layout.addLayout(buttons_layout) dlg.setLayout(main_layout) leNodeName = QLineEdit() leNodeLabel = QLineEdit() cbxNodeType = QComboBox() self.leImagePath = QLineEdit() leImageBtn = QPushButton(clicked=self.open_file, icon=QIcon('icons/folder.png')) pbOK = QPushButton() pbCancel = QPushButton() cbxNodeType.addItems(["Red Node", "Blue Node", "White Node"]) pbOK.setText("&OK") pbCancel.setText("&Cancel") l.setWidget(0, QFormLayout.LabelRole, QLabel("Node Name")) l.setWidget(0, QFormLayout.FieldRole, leNodeName) l.setWidget(1, QFormLayout.LabelRole, QLabel("Node Label")) l.setWidget(1, QFormLayout.FieldRole, leNodeLabel) l.setWidget(2, QFormLayout.LabelRole, QLabel("Node Type")) l.setWidget(2, QFormLayout.FieldRole, cbxNodeType) l.setWidget(3, QFormLayout.LabelRole, QLabel("Node Image")) l.setWidget(3, QFormLayout.FieldRole, self.leImagePath) l.addWidget(leImageBtn) def ok(): dlg.OK = True dlg.node_name = leNodeName.text() dlg.node_label = leNodeLabel.text() if self.leImagePath.text(): dlg.node_type = self.leImagePath.text() else: if 'Red Node' in cbxNodeType.currentText(): dlg.node_type = 'icons/red_circle.png' if 'Blue Node' in cbxNodeType.currentText(): dlg.node_type = 'icons/blue_circle.png' if 'White Node' in cbxNodeType.currentText(): dlg.node_type = 'icons/white_circle.png' dlg.close() def cancel(): self.ok = False dlg.close() pbOK.clicked.connect(ok) pbCancel.clicked.connect(cancel) buttons_layout.addWidget(pbOK) buttons_layout.addWidget(pbCancel) dlg.exec_() # node_name, okPressed = QInputDialog.getText(wi, "Node name","Node name:", QLineEdit.Normal, "") #TODO if cancel is selected, we can no longer add nodes if self.ok: if dlg.node_name != '' and dlg.node_label!='': self.qgv.addNode(self.qgv.engine.graph, dlg.node_name, label=dlg.node_label, shape=dlg.node_type) self.qgv.build() self.node_added.emit() else: QMessageBox.information(self, 'Incorrect Input', 'Node must have a name and a label.') def remove_node(): self.qgv.manipulation_mode = QGraphVizManipulationMode.Node_remove_Mode for btn in buttons_list: btn.setChecked(False) btnRemoveNode.setChecked(True) def remove_edge(): self.qgv.manipulation_mode = QGraphVizManipulationMode.Edge_remove_Mode for btn in buttons_list: btn.setChecked(False) btnRemoveEdge.setChecked(True) def add_edge(): self.qgv.manipulation_mode = QGraphVizManipulationMode.Edges_Connect_Mode for btn in buttons_list: btn.setChecked(False) btnAddEdge.setChecked(True) # Add buttons btnNew = QPushButton("New") btnNew.clicked.connect(new) btnOpen = QPushButton("Open") btnOpen.clicked.connect(load) btnSave = QPushButton("Save") btnSave.clicked.connect(save) hpanel.addWidget(btnNew) hpanel.addWidget(btnOpen) hpanel.addWidget(btnSave) buttons_list = [] btnManip = QPushButton("Manipulate") btnManip.setCheckable(True) btnManip.setChecked(True) btnManip.clicked.connect(manipulate) hpanel.addWidget(btnManip) buttons_list.append(btnManip) btnAddNode = QPushButton("Add Node") btnAddNode.clicked.connect(add_node) hpanel.addWidget(btnAddNode) buttons_list.append(btnAddNode) btnRemoveNode = QPushButton("Remove Node") btnRemoveNode.setCheckable(True) btnRemoveNode.clicked.connect(remove_node) hpanel.addWidget(btnRemoveNode) buttons_list.append(btnRemoveNode) btnAddEdge = QPushButton("Add Edge") btnAddEdge.setCheckable(True) btnAddEdge.clicked.connect(add_edge) hpanel.addWidget(btnAddEdge) buttons_list.append(btnAddEdge) btnRemoveEdge = QPushButton("Remove Edge") btnRemoveEdge.setCheckable(True) btnRemoveEdge.clicked.connect(remove_edge) hpanel.addWidget(btnRemoveEdge) buttons_list.append(btnRemoveEdge) btnExport = QPushButton("Export Graph") btnExport.clicked.connect(self.export_action) hpanel.addWidget(btnExport) buttons_list.append(btnExport) self.setWindowTitle('Graph View') self.setLayout(self.layout)