Examples
The examples here can be found in the examples folder in the project’s repository root.
How to run the examples
To run test you will need Conda and conda-devenv to setup the environment.
git clone https://github.com/ESSS/qmxgraph.git
cd qmxgraph
git clone --depth=1 --branch v3.7.5 https://github.com/jgraph/mxgraph.git
conda devenv
conda activate qmxgraph
inv qrc
# Hello world example.
python examples/hello_world/main.py
# Drag and drop example.
python examples/drag_and_drop/main.py
Hello world
1"""
2We all love "hello world" examples =)
3"""
4
5import sys
6
7from PyQt5 import QtWidgets
8from PyQt5.QtCore import QSize
9from PyQt5.QtWidgets import QMainWindow
10
11from qmxgraph.widget import QmxGraph
12
13
14class HelloWorldWindow(QMainWindow):
15 def __init__(self):
16 QMainWindow.__init__(self)
17
18 self.setMinimumSize(QSize(640, 480))
19 self.setWindowTitle("Qmx Hello World")
20
21 self.graph_widget = QmxGraph(parent=self)
22 # Only operate with the qmx's api after the widget has been loaded.
23 self.graph_widget.loadFinished.connect(self.graph_load_handler)
24 self.setCentralWidget(self.graph_widget)
25
26 def graph_load_handler(self, is_loaded):
27 assert is_loaded
28 qmx = self.graph_widget.api
29 v0_id = qmx.insert_vertex(x=100, y=100, width=50, height=100, label="Qmx")
30 v1_id = qmx.insert_vertex(x=400, y=300, width=100, height=50, label="World")
31 qmx.insert_edge(source_id=v0_id, target_id=v1_id, label="Hello")
32
33
34if __name__ == "__main__":
35 app = QtWidgets.QApplication(sys.argv)
36 mainWin = HelloWorldWindow()
37 mainWin.show()
38 sys.exit(app.exec_())
Basic on styles
1"""
2Display the use of styles. This is similar to the hello world sample.
3"""
4
5import sys
6
7from PyQt5 import QtWidgets
8from PyQt5.QtCore import QSize
9from PyQt5.QtWidgets import QMainWindow
10
11from qmxgraph.configuration import GraphStyles
12from qmxgraph.widget import QmxGraph
13
14
15class StyleWindow(QMainWindow):
16 def __init__(self):
17 QMainWindow.__init__(self)
18
19 self.setMinimumSize(QSize(640, 480))
20 self.setWindowTitle("Qmx Styles")
21
22 styles_cfg = {
23 "round_node": {
24 "shape": "ellipse",
25 "fill_color": "#D88",
26 "vertical_label_position": "bottom",
27 "vertical_align": "top",
28 },
29 "bold_edge": {
30 "end_arrow": "classic",
31 "shape": "connector",
32 "stroke_width": 5.0,
33 },
34 }
35
36 self.graph_widget = QmxGraph(styles=GraphStyles(styles_cfg), parent=self)
37 # Only operate with the qmx's api after the widget has been loaded.
38 self.graph_widget.loadFinished.connect(self.graph_load_handler)
39 self.setCentralWidget(self.graph_widget)
40
41 def graph_load_handler(self, is_loaded):
42 assert is_loaded
43 qmx = self.graph_widget.api
44 v0_id = qmx.insert_vertex(x=100, y=100, width=50, height=50, label="AAA")
45 # Style by configured style name.
46 v1_id = qmx.insert_vertex(
47 x=400,
48 y=100,
49 width=100,
50 height=50,
51 label="BBB",
52 style="round_node",
53 )
54 # Style by explicit values.
55 v2_id = qmx.insert_vertex(
56 x=200,
57 y=300,
58 width=50,
59 height=100,
60 label="CCC",
61 style="fillColor=#8D8",
62 )
63
64 qmx.insert_edge(source_id=v0_id, target_id=v1_id, label="normal")
65 qmx.insert_edge(source_id=v1_id, target_id=v2_id, label="bold", style="bold_edge")
66
67
68if __name__ == "__main__":
69 app = QtWidgets.QApplication(sys.argv)
70 mainWin = StyleWindow()
71 mainWin.show()
72 sys.exit(app.exec_())
Drag&drop and events bridge
1"""
2Display drag from the app into the graph widget and the event bridge.
3This is similar to the hello world sample.
4"""
5
6import sys
7
8from PyQt5 import QtWidgets
9from PyQt5.QtCore import QSize
10from PyQt5.QtGui import QDrag
11from PyQt5.QtWidgets import QGridLayout
12from PyQt5.QtWidgets import QMainWindow
13from PyQt5.QtWidgets import QPushButton
14from PyQt5.QtWidgets import QVBoxLayout
15from PyQt5.QtWidgets import QWidget
16
17import qmxgraph.mime
18from qmxgraph.widget import QmxGraph
19
20
21def create_drag_button(text, qmx_style, parent=None):
22 button = DragButton(parent)
23 button.setText(text)
24 # # You can set an icon to the button with:
25 # button.setIcon(...)
26 button.setProperty("qmx_style", qmx_style)
27 button.setToolTip("Drag me into the graph widget")
28 return button
29
30
31class DragButton(QPushButton):
32 """
33 Start a drag even with custom data.
34 """
35
36 def mousePressEvent(self, event):
37 mime_data = qmxgraph.mime.create_qt_mime_data(
38 {
39 "vertices": [
40 {
41 "dx": 0,
42 "dy": 0,
43 "width": 120,
44 "height": 40,
45 "label": self.text(),
46 "style": self.property("qmx_style"),
47 }
48 ]
49 }
50 )
51
52 drag = QDrag(self)
53 drag.setMimeData(mime_data)
54 # # You can set icons like the following:
55 # w, h = self.property('component_size')
56 # # Image displayed while dragging.
57 # drag.setPixmap(self.icon().pixmap(w, h))
58 # # Position of the image where the mouse is centered.
59 # drag.setHotSpot(QPoint(w // 2, h // 2)
60 drag.exec_()
61
62
63class DragAndDropWindow(QMainWindow):
64 def __init__(self):
65 QMainWindow.__init__(self)
66
67 self.setProperty("name", "adas")
68 self.setMinimumSize(QSize(640, 480))
69 self.setWindowTitle("Drag&Drop Styles")
70
71 central_widget = QWidget(self)
72 self.setCentralWidget(central_widget)
73
74 self.button_pane = QWidget(self)
75 self.button_pane.setEnabled(False)
76 red_button = create_drag_button("RED", "fillColor=#D88", self.button_pane)
77 green_button = create_drag_button("GREEN", "fillColor=#8D8", self.button_pane)
78 blue_button = create_drag_button("BLUE", "fillColor=#88D", self.button_pane)
79
80 self.graph_widget = QmxGraph(parent=central_widget)
81 self.events_bridge = self.create_events_bridge()
82 self.graph_widget.loadFinished.connect(self.graph_load_handler)
83
84 main_layout = QGridLayout(self)
85 central_widget.setLayout(main_layout)
86 main_layout.addWidget(self.graph_widget, 0, 0)
87 main_layout.addWidget(self.button_pane, 0, 1)
88
89 buttons_layout = QVBoxLayout(self.button_pane)
90 self.button_pane.setLayout(buttons_layout)
91 buttons_layout.addWidget(red_button)
92 buttons_layout.addWidget(green_button)
93 buttons_layout.addWidget(blue_button)
94
95 def create_events_bridge(self):
96 ##################################
97 # Based in `EventsBridge` docstring.
98
99 def on_cells_added_handler(cell_ids):
100 print(f"added {cell_ids}")
101 qmx = widget.api
102 for cid in cell_ids:
103 label = qmx.get_label(cid)
104 qmx.set_label(cid, f"{label} ({cid})")
105
106 def on_terminal_changed_handler(cell_id, terminal_type, new_terminal_id, old_terminal_id):
107 print(
108 f"{terminal_type} of {cell_id} changed from"
109 f" {old_terminal_id} to {new_terminal_id}"
110 )
111
112 def on_cells_removed_handler(cell_ids):
113 print(f"removed {cell_ids}")
114
115 def on_cells_bounds_changed_handler(changed_cell_bounds):
116 print(f"cells bounds changed {changed_cell_bounds}")
117
118 widget = self.graph_widget
119 events_bridge = widget.events_bridge
120
121 events_bridge.on_cells_added.connect(on_cells_added_handler)
122 events_bridge.on_cells_removed.connect(on_cells_removed_handler)
123 events_bridge.on_terminal_changed.connect(on_terminal_changed_handler)
124 events_bridge.on_cells_bounds_changed.connect(on_cells_bounds_changed_handler)
125
126 #
127 ##################################
128 return events_bridge
129
130 def graph_load_handler(self, is_loaded):
131 self.button_pane.setEnabled(is_loaded)
132
133
134if __name__ == "__main__":
135 app = QtWidgets.QApplication(sys.argv)
136 mainWin = DragAndDropWindow()
137 mainWin.show()
138 sys.exit(app.exec_())