I was wondering if it was possible to undraw previously drawn shapes from a loop. I have this function that'll create squares on click however I want to make it so that when the same area is clicked a second time the square will undraw.
from graphics import *
def createGrid():
X = 0
Y = 0
gridSize = 5
for i in range(1, gridSize + 1):
for j in range(1, gridSize + 1):
gridSquare = Rectangle(Point(X, Y), Point(X + 100, Y + 100))
gridSquare.draw(win)
X = X + 100
Y = Y + 100
X = 0
def editMode():
SelectedSquare = []
instruction = input("> ")
if instruction == "s":
selectionMode(SelectedSquare)
def selectionMode(SelectedSquare):
editSquare = Rectangle(Point(0, 0), Point(20, 20))
editSquare.setFill("black")
editSquare.draw(win)
while True:
selection = win.getMouse()
clickXPos = selection.getX()
clickYPos = selection.getY()
if clickXPos > 20 and clickYPos > 20:
PosX, PosY = clickXPos - (clickXPos % 100), clickYPos - (clickYPos % 100)
SelectedSquare = SelectedSquare + [Point(PosX, PosY)]
rect = Rectangle(Point(PosX, PosY), Point(PosX + 100, PosY + 100))
rect.setWidth(5)
rect.draw(win)
else:
editSquare.undraw()
break
win = GraphWin("GRID", 500, 500)
createGrid()
while True:
editMode()
As you can see, on click, there will be a thicker border around the grid square that was selected, I would like to be able to 1) remove the thickened border if clicked a second time 2) be able to remove all thickened borders surrounding grid squares but I just cannot seem to figure this out, any help would be greatly appreciated!
The general problem seems to be that you have no underlying data structure or logic for your program -- you're drawing the interface first and then trying to make its behaviors define the program.
Below I've patched your code to have the points on the selected squares list remember what rectangle was drawn to highlight them, so if they are selected again, the highlight can be undone and the point removed:
from graphics import *
GRID_SIZE = 5
SQUARE_SIZE = 100
EDIT_BUTTON_SIZE = 20
BORDER_WIDTH = 5
def createGrid():
X, Y = 0, 0
for _ in range(1, GRID_SIZE + 1):
for _ in range(1, GRID_SIZE + 1):
gridSquare = Rectangle(Point(X, Y), Point(X + SQUARE_SIZE, Y + SQUARE_SIZE))
gridSquare.draw(win)
X += SQUARE_SIZE
Y += SQUARE_SIZE
X = 0
def editMode():
selectedSquares = []
instruction = input("> ")
if instruction == "s":
selectionMode(selectedSquares)
def checkSelected(point, squares):
for selected in squares:
if point.getX() == selected.getX() and point.getY() == selected.getY():
return selected
return None
def selectionMode(selectedSquares):
editSquare = Rectangle(Point(0, 0), Point(EDIT_BUTTON_SIZE, EDIT_BUTTON_SIZE))
editSquare.setFill("black")
editSquare.draw(win)
while True:
selection = win.getMouse()
clickXPos = selection.getX()
clickYPos = selection.getY()
if clickXPos <= EDIT_BUTTON_SIZE and clickYPos <= EDIT_BUTTON_SIZE:
break
PosX, PosY = clickXPos - clickXPos % SQUARE_SIZE, clickYPos - clickYPos % SQUARE_SIZE
point = Point(PosX, PosY)
selected = checkSelected(point, selectedSquares)
if selected:
selected.rect.undraw()
selectedSquares.remove(selected)
else:
rect = Rectangle(point, Point(PosX + SQUARE_SIZE, PosY + SQUARE_SIZE))
rect.setWidth(BORDER_WIDTH)
rect.draw(win)
point.rect = rect
selectedSquares.append(point)
editSquare.undraw()
win = GraphWin("GRID", GRID_SIZE * SQUARE_SIZE, GRID_SIZE * SQUARE_SIZE)
createGrid()
while True:
editMode()
But this is only a band-aid -- as you add more functionality the issue of a lack of data structure and spelled out logic will continue to frustrate you.