yyy2.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. import tkinter as tk
  2. class SquareWindow:
  3. def __init__(self):
  4. # Configuration: [(parent_number, count), ...]
  5. # (None, 11) means draw 11 squares inside square #0 (the main square)
  6. # (2, 7) means draw 7 squares inside square #2
  7. self.config = [(None, 3), (1, 66), (2, 23), (55, 7), (98, 5)]
  8. # Set window size to 1000x1000 pixels (needed for calculate_squares)
  9. self.window_size = 1000
  10. # Calculate squares based on config
  11. self.squares = self.calculate_squares()
  12. # Create the main window
  13. self.root = tk.Tk()
  14. self.root.title("Square Window")
  15. self.root.geometry(f"{self.window_size}x{self.window_size}")
  16. # Create a canvas to draw on
  17. self.canvas = tk.Canvas(self.root, width=self.window_size, height=self.window_size, bg="white")
  18. self.canvas.pack(fill=tk.BOTH, expand=True)
  19. # Property to store square information: {number: (x, y, size, parent_number)}
  20. self.square_positions = {}
  21. # Draw all squares based on the calculated squares dictionary
  22. for number, (x, y, size, parent_number) in self.squares.items():
  23. self.draw_square_at_location(x, y, size, number, parent_number)
  24. # Print the square positions dictionary
  25. output_content = f"Square positions: {self.square_positions}"
  26. print(output_content)
  27. # Save the output to print.log file
  28. with open("print.log", "w", encoding="utf-8") as f:
  29. f.write(output_content)
  30. def calculate_squares(self):
  31. """
  32. Calculate all squares based on the config.
  33. Config format: [(parent_number, count), ...]
  34. (None, count) means draw 'count' squares inside the main square (number 0)
  35. (number, count) means draw 'count' squares inside square with 'number'
  36. """
  37. import math
  38. # Initialize the main square (number 0)
  39. main_square_size = int(self.window_size * 0.9) # 90% of 1000 = 900
  40. margin = (self.window_size - main_square_size) // 2 # (1000 - 900) / 2 = 50
  41. # Dictionary to store all squares: {number: (x, y, size, parent_number)}
  42. squares = {}
  43. # Add the main square (number 0)
  44. squares[0] = (margin, margin, main_square_size, None)
  45. # Track the next available number for new squares
  46. next_number = 1
  47. # Process each configuration entry
  48. for parent_number, count in self.config:
  49. if parent_number is None:
  50. # Draw 'count' squares inside the main square (number 0)
  51. parent_num = 0
  52. else:
  53. parent_num = parent_number
  54. # Get the parent square's info
  55. if parent_num in squares:
  56. parent_x, parent_y, parent_size, _ = squares[parent_num]
  57. # Calculate grid size for the child squares
  58. n = math.ceil(math.sqrt(count)) # Number of rows/columns needed
  59. child_size = (parent_size // n) - 2 # Size of each child square minus padding
  60. # Calculate spacing to distribute squares evenly with gaps
  61. total_used_space = n * child_size # Total space occupied by squares
  62. remaining_space = parent_size - total_used_space # Remaining space for gaps
  63. gap = remaining_space // (n + 1) # Gap between squares and margins
  64. # Draw 'count' child squares inside the parent square
  65. squares_drawn = 0
  66. for i in range(n): # Rows
  67. for j in range(n): # Columns
  68. if squares_drawn >= count:
  69. break
  70. # Calculate position for each child square with proper spacing
  71. child_x = parent_x + gap + j * (child_size + gap)
  72. child_y = parent_y + gap + i * (child_size + gap)
  73. # Add the child square to the dictionary
  74. squares[next_number] = (child_x, child_y, child_size, parent_num)
  75. next_number += 1
  76. squares_drawn += 1
  77. if squares_drawn >= count:
  78. break
  79. return squares
  80. def draw_square_at_location(self, x, y, size, number, parent_number):
  81. """
  82. Draw a square at a specific location with a number in the center.
  83. Args:
  84. x: X coordinate of the top-left corner
  85. y: Y coordinate of the top-left corner
  86. size: Size of the square (width and height)
  87. number: Number to display in the center
  88. parent_number: The number of the parent square (None if no parent)
  89. """
  90. # Calculate the level of the square (how deep it is in the hierarchy)
  91. level = self.get_square_level(number)
  92. # Define light colors for different levels (with transparency effect)
  93. colors = [
  94. "#E0E0E0", # Level 0 (light gray, main square)
  95. "#FFCCCC", # Level 1 (light red)
  96. "#CCE5FF", # Level 2 (light blue)
  97. "#CCFFCC", # Level 3 (light green)
  98. "#E5CCFF", # Level 4 (light purple)
  99. "#FFE5CC", # Level 5 (light orange)
  100. "#D9CCAA", # Level 6 (light brown)
  101. "#FFD9E5", # Level 7 (light pink)
  102. "#FFFFCC", # Level 8 (light yellow)
  103. "#CCFFFF" # Level 9+ (light cyan)
  104. ]
  105. # Select color based on level
  106. color = colors[level] if level < len(colors) else "gray"
  107. # Draw the square with light colored fill (simulating transparency) and darker outline
  108. outline_color = color.replace("#", "") # Get hex color without #
  109. # Darken the outline color by reducing RGB values
  110. if len(outline_color) == 6:
  111. # Convert hex to RGB, then darken
  112. r = max(0, int(outline_color[0:2], 16) - 60)
  113. g = max(0, int(outline_color[2:4], 16) - 60)
  114. b = max(0, int(outline_color[4:6], 16) - 60)
  115. dark_outline = f"#{r:02x}{g:02x}{b:02x}"
  116. else:
  117. dark_outline = "black" # fallback
  118. self.canvas.create_rectangle(x, y, x + size, y + size, outline=dark_outline, fill=color, width=1)
  119. # Add number in the center of the square (ensure it's drawn last so it's not covered)
  120. center_x = x + size // 2
  121. center_y = y + size // 2
  122. # Use black text for better contrast against any background
  123. self.canvas.create_text(center_x, center_y, text=str(number), fill="black", font=("Arial", 10))
  124. # Record the square's position information
  125. self.square_positions[number] = (x, y, size, parent_number)
  126. def get_square_level(self, number):
  127. """
  128. Calculate the level of a square in the hierarchy.
  129. Level 0: Main square (number 0)
  130. Level 1: Direct children of main square
  131. Level 2: Children of level 1 squares
  132. etc.
  133. """
  134. if number == 0:
  135. return 0
  136. level = 1 # Start at level 1 since we're past the main square
  137. current_parent = self.squares[number][3] # Get parent number from (x, y, size, parent_number)
  138. while current_parent is not None:
  139. level += 1
  140. if current_parent == 0:
  141. break
  142. current_parent = self.squares[current_parent][3] # Get parent's parent
  143. return level
  144. def run(self):
  145. self.root.mainloop()
  146. if __name__ == "__main__":
  147. app = SquareWindow()
  148. app.run()