"""
GUI visualization components for Red-Black Tree display using PyQt5.
This module provides graphical user interface components for visualizing Red-Black Trees.
It includes window management and interactive tree visualization capabilities that allow
users to see the structure, colors, and properties of Red-Black Trees in real-time.
Classes
-------
TreeWindow
Main application window that hosts the Red-Black Tree visualization.
Manages window properties, size, and title for the tree display.
TreeView
Custom graphics view widget that renders Red-Black Tree nodes and edges.
Provides interactive visualization with proper node coloring and positioning.
"""
from typing import Optional
from config import COLORS
from red_black_tree import RedBlackTree
from PyQt5.QtWidgets import QMainWindow, QGraphicsView
from PyQt5.QtGui import QBrush, QPen
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QGraphicsScene, QGraphicsEllipseItem, QGraphicsTextItem, QGraphicsLineItem
[docs]
class TreeWindow(QMainWindow):
"""
A class to create a window for visualizing a Red-Black Tree using PyQt5.
Inherits from QMainWindow: The main window class from PyQt5.
"""
currentWindow: Optional['TreeWindow'] = None
def __init__(self):
super().__init__()
self.setWindowTitle("Árbol Rojo-Negro")
self.resize(800, 600)
# ...
[docs]
class TreeView(QGraphicsView):
"""
A class to visualize a Red-Black Tree using PyQt5.
Args:
tree (RedBlackTree): The Red-Black Tree to visualize.
Inherits from QGraphicsView: A widget that provides a view of a QGraphicsScene.
"""
def __init__(self, tree: RedBlackTree):
super().__init__()
self.tree = tree
self.graphics_scene = QGraphicsScene()
self.setScene(self.graphics_scene)
self.__draw_tree()
def __draw_tree(self) -> None:
"""
Draw the tree in the scene.
"""
self.graphics_scene.clear()
if self.tree.root is None:
return
stack = [(self.tree.root, 0, 0, 500)]
while stack:
node, x, y, offset = stack.pop()
ellipse = QGraphicsEllipseItem(x - 20, y - 20, 40, 40)
ellipse.setBrush(QBrush(Qt.GlobalColor.red if node.color == COLORS.RED else Qt.GlobalColor.black))
self.graphics_scene.addItem(ellipse)
bh = QGraphicsTextItem(str(node.black_height))
bh.setDefaultTextColor(Qt.GlobalColor.black)
bh.setPos(x + 8, y + 8)
self.graphics_scene.addItem(bh)
node_data = str(node.data)
#node_data = node_data if len(node_data) < 3 else node_data[:2] + "."
text = QGraphicsTextItem(node_data)
text.setDefaultTextColor(Qt.GlobalColor.cyan)
text.setPos(x - 10, y - 10)
self.graphics_scene.addItem(text)
if node.left:
self.__draw_line(x, y, x - offset, y + 80)
stack.append((node.left, x - offset, y + 80, offset // 2))
if node.right:
self.__draw_line(x, y, x + offset, y + 80)
stack.append((node.right, x + offset, y + 80, offset // 2))
def __draw_line(self, x0: float, y0: float, x1: float, y1: float) -> None:
"""
Draw a line between two points in the scene.
Args:
x0 (float): The x coordinate of the first point.
y0 (float): The y coordinate of the first point.
x1 (float): The x coordinate of the second point.
y1 (float): The y coordinate of the second point.
"""
line = QGraphicsLineItem(x0, y0, x1, y1)
line.setPen(QPen(Qt.GlobalColor.black, 2))
self.graphics_scene.addItem(line)