Python Tkinter画布闪烁

Python Tkinter画布闪烁,python,tkinter,Python,Tkinter,我试图用Tkinter在Python中实现一个简单的乒乓球游戏,但不幸的是,我遇到了一些关于闪烁的主要问题。我正在使用一个覆盖整个窗口的画布小部件,并且每秒在画布上绘制多次矩形。当我这样做时,所有绘制的矩形在游戏运行时都会定期闪烁,在再次出现之前消失几秒钟 下面是我在游戏中绘图时使用的逻辑的一个简单示例,通过运行它,您应该能够看到闪烁的动作: from tkinter import * import threading, time def loop(): FRAME_TIME = 1

我试图用Tkinter在Python中实现一个简单的乒乓球游戏,但不幸的是,我遇到了一些关于闪烁的主要问题。我正在使用一个覆盖整个窗口的画布小部件,并且每秒在画布上绘制多次矩形。当我这样做时,所有绘制的矩形在游戏运行时都会定期闪烁,在再次出现之前消失几秒钟

下面是我在游戏中绘图时使用的逻辑的一个简单示例,通过运行它,您应该能够看到闪烁的动作:

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()

你知道是什么原因吗?

你的脚本完全不需要线程(Tkinter不喜欢线程)

对于循环,应该使用
小部件.after()
而不是无限

我想你应该定义画布和画布上的矩形,在一个函数中你应该移动其他小部件。在这种情况下,您不应该删除/重新创建小部件

黑色“背景”(矩形)是静态的,在脚本运行期间不会更新。已在画布上创建了一个椭圆形小部件(
create_oval()
),该小部件在
render
函数中移动(在-3和3之间随机更改X-Y位置)

canvas.after(10,render)
意味着每隔10秒一次调用
render
函数。因此,实际上这是一个动画,椭圆将始终在画布上移动

示例:

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:

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()


我认为这是一个很好的起点,您可以实现完整的乒乓球游戏。

您不需要线程来实现这一点。另外,不要删除并重新创建矩形,只需移动它即可。有关使用tkinter制作动画的正确方法的示例,请参见。@Bryan Oakley。谢谢,你的评论解决了我的问题。遗憾的是,我没有答案可以接受。+1“
Tkinter
不喜欢线程”。这是非常正确的,多年来,已经导致了tkinter模块增加了许多解决方案。目前的情况是tkinter互斥互斥和GIL之间的谨慎平衡,但在某些情况下,使用tkinter线程仍然可以使CPython解释器崩溃。小结:尽可能避免这种组合。我完全同意你的看法。我希望tk/python的这种情况将是一个有趣的记忆,因为头是未来