0

tkinter gui glitching out

anyone know why my tkinter is glitching out like this after around 2.5 minutes?

this code is the minimum example so it wont have the coloured cells but it is the same problem

from tkinter import *
import random

tk = Tk()
tk.wm_title("Battleship")
# forming tkinter window

def baseGrid():
    tk.player_canvas = Canvas(tk, height=300, width=300, highlightbackground='black', highlightthickness=0.5)
    tk.ai_canvas = Canvas(tk, height=300, width=300, highlightbackground='black', highlightthickness=0.5)
    tk.player_canvas.grid(row=1, column=0, padx=50)
    tk.ai_canvas.grid(row=1, column=1, padx=50)
    for x in range(10):
        for y in range(10):
            tk.player_canvas.create_rectangle(x * 30, y * 30, 300, 300, fill='white')
            tk.ai_canvas.create_rectangle(x * 30, y * 30, 300, 300, fill='white')


while True:
    tk.update()
    tk.update_idletasks()
    place = baseGrid()

  • 1
    In the code you posted, you create an infinite amount of `Canvas` items, since every call to `baseGrid` creates two new canvases and you call `baseGrid` in you `while True` loop. Do you do the same in your actual code? If so, you should change it to creating the canvases only once and updating them (although probably not in a `while True` loop). – fhdrsdg Nov 12 '19 at 13:17
  • 1
    First you have to understand [Event-driven programming](https://stackoverflow.com/a/9343402/7414759) and [Tkinter understanding mainloop](https://stackoverflow.com/questions/29158220/tkinter-understanding-mainloop) – stovfl Nov 12 '19 at 13:32

1 Answers1

2

Your loop was causing a memory leak. I'm not sure exactly because I didn't test what was causing it, but I'm almost positive it was because you were drawing an infinite amount of rectangles on top of each other. I simply just changed your code to how I would write it to fix it.

from tkinter import *
import random

tk = Tk()
tk.wm_title("Battleship")
# forming tkinter window

# While technically you can add the canvas objects to your window I don't know if that is best practice.
player_canvas = Canvas(tk, height=300, width=300, highlightbackground='black', highlightthickness=0.5)
ai_canvas = Canvas(tk, height=300, width=300, highlightbackground='black', highlightthickness=0.5)


def baseGrid():
    player_canvas.grid(row=1, column=0, padx=50)
    ai_canvas.grid(row=1, column=1, padx=50)
    for x in range(10):
        for y in range(10):
            player_canvas.create_rectangle(x * 30, y * 30, 300, 300, fill='white')
            ai_canvas.create_rectangle(x * 30, y * 30, 300, 300, fill='white')


baseGrid()  # you are not returning anything so you do not need the place variable

tk.mainloop()  # you should just run mainloop so that Tkinter can manage the loop.

ShayneLoyd
  • 633
  • 1
  • 4
  • 9