Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tkinter canvas flickering

Tags:

python

tkinter

I'm attempting to implement a simple Pong game in Python using Tkinter, but unfortunately I'm having some major issues with flickering. I'm using a Canvas widget that covers the entire window and I'm drawing rectangles on said canvas many times per second. When I do this all drawn rectangles flicker regularly while the game is running, disappearing for a fraction of a second before appearing again.

A simple example of the logic I use for drawing in my game can be seen below, by running it you should be able to see the flickering in action:

from tkinter import *
import threading, time

def loop():
    FRAME_TIME = 1 / 60
    while True:
        render()
        time.sleep(FRAME_TIME)

def render():
    canvas.delete(ALL)
    canvas.create_rectangle(0, 0, WIDTH, HEIGHT, fill='black')

WIDTH = 800
HEIGHT = 600

root = Tk()
canvas = Canvas(root, width=800, height=600)
canvas.pack()
threading.Thread(target=loop, daemon=True).start()
root.mainloop()

Any ideas as to what is causing it?

like image 609
Just some guy Avatar asked Nov 08 '22 04:11

Just some guy


1 Answers

The threading is totally not needed for your script (The Tkinter doesn't love the threading).

You should use the widget.after() instead of infinite for loop.

I guess you should define the canvas and the rectangle on the canvas and in a function you should move the other widgets. In this case you shouldn't delete/recreate the widgets.

The black "background" (rectangle) is static and it is not updated during the script running. An oval widget has been created on the canvas (create_oval()) and this widget moves in the render function (randomly change the X-Y positions between -3 and 3).

The canvas.after(10, render) means to call again-and-again the render function in every 10 secs. So actually it is an animation and the oval will move always on your canvas.

Example:

from tkinter import *
import random


def render():
    canvas.move(oval, random.randint(-3, 3), random.randint(-3, 3))
    canvas.after(10, render)


WIDTH = 800
HEIGHT = 600

root = Tk()
canvas = Canvas(root, width=800, height=600)
canvas.create_rectangle(0, 0, WIDTH, HEIGHT, fill="black")
oval = canvas.create_oval(400, 400, 410, 410, fill="red")
canvas.pack()
render()
root.mainloop()

GUI:

gui example

I think it is a good starting point for you to implement the complete pong game.

like image 96
milanbalazs Avatar answered Nov 15 '22 07:11

milanbalazs