| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- import tkinter as tk
- class SquareWindow:
- def __init__(self):
- # Configuration: [(parent_number, count), ...]
- # (None, 11) means draw 11 squares inside square #0 (the main square)
- # (2, 7) means draw 7 squares inside square #2
- self.config = [(None, 3), (1, 66), (2, 23), (55, 7), (98, 5)]
-
- # Set window size to 1000x1000 pixels (needed for calculate_squares)
- self.window_size = 1000
-
- # Calculate squares based on config
- self.squares = self.calculate_squares()
-
- # Create the main window
- self.root = tk.Tk()
- self.root.title("Square Window")
-
- self.root.geometry(f"{self.window_size}x{self.window_size}")
-
- # Create a canvas to draw on
- self.canvas = tk.Canvas(self.root, width=self.window_size, height=self.window_size, bg="white")
- self.canvas.pack(fill=tk.BOTH, expand=True)
-
- # Property to store square information: {number: (x, y, size, parent_number)}
- self.square_positions = {}
-
- # Draw all squares based on the calculated squares dictionary
- for number, (x, y, size, parent_number) in self.squares.items():
- self.draw_square_at_location(x, y, size, number, parent_number)
-
- # Print the square positions dictionary
- output_content = f"Square positions: {self.square_positions}"
- print(output_content)
-
- # Save the output to print.log file
- with open("print.log", "w", encoding="utf-8") as f:
- f.write(output_content)
-
- def calculate_squares(self):
- """
- Calculate all squares based on the config.
- Config format: [(parent_number, count), ...]
- (None, count) means draw 'count' squares inside the main square (number 0)
- (number, count) means draw 'count' squares inside square with 'number'
- """
- import math
-
- # Initialize the main square (number 0)
- main_square_size = int(self.window_size * 0.9) # 90% of 1000 = 900
- margin = (self.window_size - main_square_size) // 2 # (1000 - 900) / 2 = 50
-
- # Dictionary to store all squares: {number: (x, y, size, parent_number)}
- squares = {}
-
- # Add the main square (number 0)
- squares[0] = (margin, margin, main_square_size, None)
-
- # Track the next available number for new squares
- next_number = 1
-
- # Process each configuration entry
- for parent_number, count in self.config:
- if parent_number is None:
- # Draw 'count' squares inside the main square (number 0)
- parent_num = 0
- else:
- parent_num = parent_number
-
- # Get the parent square's info
- if parent_num in squares:
- parent_x, parent_y, parent_size, _ = squares[parent_num]
-
- # Calculate grid size for the child squares
- n = math.ceil(math.sqrt(count)) # Number of rows/columns needed
- child_size = (parent_size // n) - 2 # Size of each child square minus padding
-
- # Calculate spacing to distribute squares evenly with gaps
- total_used_space = n * child_size # Total space occupied by squares
- remaining_space = parent_size - total_used_space # Remaining space for gaps
- gap = remaining_space // (n + 1) # Gap between squares and margins
-
- # Draw 'count' child squares inside the parent square
- squares_drawn = 0
- for i in range(n): # Rows
- for j in range(n): # Columns
- if squares_drawn >= count:
- break
-
- # Calculate position for each child square with proper spacing
- child_x = parent_x + gap + j * (child_size + gap)
- child_y = parent_y + gap + i * (child_size + gap)
-
- # Add the child square to the dictionary
- squares[next_number] = (child_x, child_y, child_size, parent_num)
-
- next_number += 1
- squares_drawn += 1
- if squares_drawn >= count:
- break
-
- return squares
-
- def draw_square_at_location(self, x, y, size, number, parent_number):
- """
- Draw a square at a specific location with a number in the center.
-
- Args:
- x: X coordinate of the top-left corner
- y: Y coordinate of the top-left corner
- size: Size of the square (width and height)
- number: Number to display in the center
- parent_number: The number of the parent square (None if no parent)
- """
- # Calculate the level of the square (how deep it is in the hierarchy)
- level = self.get_square_level(number)
-
- # Define light colors for different levels (with transparency effect)
- colors = [
- "#E0E0E0", # Level 0 (light gray, main square)
- "#FFCCCC", # Level 1 (light red)
- "#CCE5FF", # Level 2 (light blue)
- "#CCFFCC", # Level 3 (light green)
- "#E5CCFF", # Level 4 (light purple)
- "#FFE5CC", # Level 5 (light orange)
- "#D9CCAA", # Level 6 (light brown)
- "#FFD9E5", # Level 7 (light pink)
- "#FFFFCC", # Level 8 (light yellow)
- "#CCFFFF" # Level 9+ (light cyan)
- ]
-
- # Select color based on level
- color = colors[level] if level < len(colors) else "gray"
-
- # Draw the square with light colored fill (simulating transparency) and darker outline
- outline_color = color.replace("#", "") # Get hex color without #
- # Darken the outline color by reducing RGB values
- if len(outline_color) == 6:
- # Convert hex to RGB, then darken
- r = max(0, int(outline_color[0:2], 16) - 60)
- g = max(0, int(outline_color[2:4], 16) - 60)
- b = max(0, int(outline_color[4:6], 16) - 60)
- dark_outline = f"#{r:02x}{g:02x}{b:02x}"
- else:
- dark_outline = "black" # fallback
-
- self.canvas.create_rectangle(x, y, x + size, y + size, outline=dark_outline, fill=color, width=1)
-
- # Add number in the center of the square (ensure it's drawn last so it's not covered)
- center_x = x + size // 2
- center_y = y + size // 2
- # Use black text for better contrast against any background
- self.canvas.create_text(center_x, center_y, text=str(number), fill="black", font=("Arial", 10))
-
- # Record the square's position information
- self.square_positions[number] = (x, y, size, parent_number)
-
- def get_square_level(self, number):
- """
- Calculate the level of a square in the hierarchy.
- Level 0: Main square (number 0)
- Level 1: Direct children of main square
- Level 2: Children of level 1 squares
- etc.
- """
- if number == 0:
- return 0
-
- level = 1 # Start at level 1 since we're past the main square
- current_parent = self.squares[number][3] # Get parent number from (x, y, size, parent_number)
-
- while current_parent is not None:
- level += 1
- if current_parent == 0:
- break
- current_parent = self.squares[current_parent][3] # Get parent's parent
-
- return level
- def run(self):
- self.root.mainloop()
- if __name__ == "__main__":
- app = SquareWindow()
- app.run()
|