如何在TKINTER中更新帆布和图像?
这是我用来在窗口中显示国际象棋板的一部分:
import tkinter as tk
from PIL import Image, ImageTk
def render():
window = tk.Tk()
window.geometry("1920x1080")
window.title("Chess 2")
frame = tk.Frame(window)
frame.pack()
canvas = tk.Canvas(frame, width=800, height=800)
canvas.pack()
boardImg = ImageTk.PhotoImage(file = r"successful projects\imgs\board.png")
canvas.create_image(400,400,image=boardImg)
whitePawnImg = ImageTk.PhotoImage(file = r"successful projects\imgs\whitePawn.png")
# ...
for y in range(len(board)):
for x in range(len(board[y])):
match board[y][x]:
case "p":
canvas.create_image(50+(x*100),50+(y*100),image=blackPawnImg)
# ...
case _:
pass
window.mainloop()
在代码中,“板”是类似so的国际象棋板的表示(缩短):
[[' ', ' '],
[' ', 'p']]
当我调用Render(),一切都很好。麻烦是,当我将列表更改为EG时。
[[' ', 'p'],
[' ', ' ']]
,然后再次调用Render()
,窗口保持不变。我想要的是董事会再次渲染所有内容。关于如何解决的任何想法?
This is a section of code which I use to display a chess board in a window:
import tkinter as tk
from PIL import Image, ImageTk
def render():
window = tk.Tk()
window.geometry("1920x1080")
window.title("Chess 2")
frame = tk.Frame(window)
frame.pack()
canvas = tk.Canvas(frame, width=800, height=800)
canvas.pack()
boardImg = ImageTk.PhotoImage(file = r"successful projects\imgs\board.png")
canvas.create_image(400,400,image=boardImg)
whitePawnImg = ImageTk.PhotoImage(file = r"successful projects\imgs\whitePawn.png")
# ...
for y in range(len(board)):
for x in range(len(board[y])):
match board[y][x]:
case "p":
canvas.create_image(50+(x*100),50+(y*100),image=blackPawnImg)
# ...
case _:
pass
window.mainloop()
In the code, "board" is a representation of a chess board like so (shortened):
[[' ', ' '],
[' ', 'p']]
When I call render()
, everything works fine. Trouble is, when I change the list to eg.
[[' ', 'p'],
[' ', ' ']]
, then call render()
again, the window stays the same. What I want is for the board to render everything again. Any ideas on how to fix?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当您将物品添加到
canvas
小部件时,使用其create_xxx()
方法之一,例如create_image()
,返回整数href =“ https://tkdocs.com/shipman/canvas-methods.html” rel =“ nofollow noreferrer”>move> move> move()
方法。这就是您需要做的一切来更新所显示的内容,不需要明确的“刷新”步骤。
例如,如果您最初在某个地方放置了典当图像:
您可以将Pawn Image 10像素移动到右侧,而将20个像素向下移动(请注意,移动量相对于其当前位置指定):
您也可以使用更多的通用
itemConfigure()
更改与Canvas
项目相关联的其他选项(例如用create_line()
)创建的行的颜色。When you add things to a
Canvas
widget, using one of itscreate_xxx()
methods, likecreate_image()
, an integerid
number is returned which you could use to move the object later via itsmove()
method.That's all you have need to do to update what's being displayed, no explicit "refresh" step is needed.
For example, if you initially placed a pawn image somewhere using:
You could move the pawn image 10 pixels to the right and 20 down via (note that the movement amounts are specified relative to its current position):
You can also use the more generic
itemconfigure()
method to change other options associated withCanvas
items (such as the color of a line created withcreate_line()
).除了绘制,重新绘制,删除或移动画布上的对象外,您无需任何其他内容即可更新画布。每当您在画布中添加一些东西时,画布都会在事件队列中添加一个事件,告诉tkinter需要刷新小部件。下次控制返回到
mainloop
,画布将自动刷新。您的代码有一个基本缺陷,每个调用
刷新
都会创建一个全新的窗口,全新的画布等。相反,您的刷新
应该与现有窗口和帆布一起使用,它要做的就是移动物品。一旦函数返回,窗口本身将自动刷新。You don't need to anything to update the canvas other than to draw, redraw, delete, or move objects on the canvas. Whenever you add something to a canvas, the canvas will add an event to the event queue telling tkinter that the widget needs to be refreshed. The next time control returns to
mainloop
, the canvas will automatically be refreshed.Your code has a fundamental flaw that each call to
refresh
will create an entirely new window, entirely new canvas, etc. Instead, yourrefresh
should work with an existing window and canvas, and all it needs to do is move items around. The window itself will automatically refresh once the function returns.