from PyQt6.QtCore import Qt from PyQt6.QtGui import QPen from PyQt6.QtWidgets import QGraphicsView, QGraphicsScene, QPushButton, QGraphicsProxyWidget from data.connect import connect, Department class DepartmentGraph(QGraphicsView): def __init__(self, parent): super().__init__() self.scene = QGraphicsScene(self) self.setScene(self.scene) with connect() as session: self.departments = session.query(Department).all() self.pushed_button = None self.parent = parent self.is_first_button = True self.nodes = {} self.render_graph() def render_graph(self): root_departments = [d for d in self.departments if d.parent_id is None] x = 50 y = 50 for root in root_departments: self.add_department_node(root, x, y) x += 900 def button_clicked(self): if self.pushed_button is not None: self.pushed_button.setStyleSheet(''' QPushButton { background-color: rgb(228, 244, 204); } ''') button = self.sender() button.setStyleSheet(''' QPushButton { background-color: #2f9836; } ''') self.pushed_button = button self.parent.select_department(button.department_id) def add_department_node(self, department, x, y, parent_item=None, level=0): button = QPushButton(department.title) button.department_id = department.id button.clicked.connect(self.button_clicked) button.setStyleSheet(''' QPushButton { background-color: rgb(228, 244, 204); } ''') if self.is_first_button: button.click() self.is_first_button = False proxy = QGraphicsProxyWidget() proxy.setWidget(button) proxy.setPos(x, y) self.scene.addItem(proxy) self.nodes[department.id] = proxy if parent_item: parent_center = parent_item.sceneBoundingRect().center() current_center = proxy.sceneBoundingRect().center() line = self.scene.addLine(parent_center.x(), parent_center.y(), current_center.x(), current_center.y(), QPen(Qt.GlobalColor.black)) child_departments = [d for d in self.departments if d.parent_id == department.id] child_x = x - len(child_departments) * 100 // 2 for index, child in enumerate(child_departments): offset_y = (index % 2) * 50 but_width = self.add_department_node(child, child_x, y + 50, proxy, level + 1) child_x += 250 return button.width()