gpt4 book ai didi

python - Tkinter Canvas 移动留下像素痕迹

转载 作者:太空宇宙 更新时间:2023-11-03 13:07:23 25 4
gpt4 key购买 nike

我正在 Tkinter Canvas 中开发一个游戏,其中点在屏幕上移动。我使用 tkinter.Canvas.create_oval(...) 将每个点放在一个位置,然后使用 tkinter.Canvas.move(pointID,delta_x,delta_y) 移动这些点.

我的问题是这些点在移动时似乎会留下痕迹。我做了一个简化的例子来说明我的问题。

from tkinter import Canvas,mainloop,Tk
import numpy as np
import random
import traceback
import threading
import time
from queue import Queue

class Point:
def __init__(self,the_canvas,uID):
self.uID = uID
self.location = np.ones((2)) * 200
self.color = "#"+"".join([random.choice('0123456789ABCDEF') for j in range(6)])
self.the_canvas = the_canvas
self.the_canvas.create_oval(200,200,200,200,
fill=self.color,outline=self.color,width=6,
tags=('runner'+str(self.uID),'runner'))
def move(self):
delta = (np.random.random((2))-.5)*20
self.the_canvas.move('runner'+str(self.uID),delta[0],delta[1])

def queue_func():
while True:
time.sleep(.25)
try:
next_action = the_queue.get(False)
next_action()
except Exception as e:
if str(e) != "":
print(traceback.format_exc())

the_queue = Queue()
the_thread = threading.Thread(target=queue_func)
the_thread.daemon = True
the_thread.start()

window = Tk()
window.geometry('400x400')
the_canvas = Canvas(window,width=400,height=400,background='black')
the_canvas.grid(row=0,column=0)

points = {}
for i in range(100):
points[i] = Point(the_canvas,i)

def random_movement():
while True:
for point in points.values():
point.move()

the_queue.put(random_movement)

mainloop()

结果是这样的:

example1

我需要能够干净利落地移动点,不留下任何东西。

  • 我尝试更改 move() 函数,以便根据其标记删除每个点并在新位置重新绘制,但这会导致同样的问题。
  • 我已经在 Canvas.oval 配置中尝试了 fill=''outline='' ,但这没有帮助。
  • 这些像素试验的行为似乎不稳定,就像它们会随着时间的推移而消失,只留下有限数量的足迹。
  • 我已经尝试从移动循环中删除 time.sleep(.2),这似乎使问题更加明显。

example2

  • 我发现清除这些流氓彩色像素的唯一方法是运行 canvas.delete("all"),所以到目前为止,我唯一的解决办法是删除所有内容并重新绘制一切不断。这对我来说似乎不是一个很好的解决方案。

避免这些“像素痕迹”的好方法是什么?这对我来说真的只是一个错误,但也许我在某个地方犯了错误。

最佳答案

经过一番挖掘,我在这里找到了这篇文章:Python3 tkinter.Canvas.move() method makes artifacts on screen

问题是椭圆的边界。所以我所做的就是移除边框并使椭圆稍微变大以进行补偿,看起来就成功了。

如果你改变这一行:

self.the_canvas.create_oval(200, 200, 200, 200, 
fill=self.color, outline=self.color, width=6,
tags=('runner' + str(self.uID), 'runner'))

对此:

self.the_canvas.create_oval(200,200,206,206,
fill=self.color,outline='', width=0,
tags=('runner'+str(self.uID),'runner'))

无论是否使用线程,问题都应该消失。

如果你想看看你的代码在没有线程的情况下会是什么样子,这里有一个例子:

import tkinter as tk
import numpy as np
import random


class Point:
def __init__(self, the_canvas, uID):
self.uID = uID
self.location = np.ones((2)) * 200
self.color = "#"+"".join([random.choice('0123456789ABCDEF') for j in range(6)])
self.the_canvas = the_canvas
self.the_canvas.create_oval(200, 200, 206, 206,
fill=self.color, outline='', width=0,
tags=('runner'+str(self.uID), 'runner'))

def move(self):
delta = (np.random.random((2))-.5)*20

self.the_canvas.move('runner'+str(self.uID), delta[0], delta[1])

window = tk.Tk()
window.geometry('400x400')
the_canvas = tk.Canvas(window, width=400, height=400, background='black')
the_canvas.grid(row=0, column=0)

points = {}
for i in range(100):
points[i] = Point(the_canvas, i)

def random_movement():
for point in points.values():
point.move()
window.after(50, random_movement)

random_movement()
window.mainloop()

结果:

enter image description here

关于python - Tkinter Canvas 移动留下像素痕迹,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54202470/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com