如何优化这个类似 Tkinter "MS Paint" 的程序?
How to optimize this Tkinter "MS Paint"-like program?
我一直在研究类似 Tkinter "Paint" 的程序,但我遇到了性能问题。我不得不设置 200 毫秒的延迟来重绘,因为没有它它真的 运行。它必须使用这个网格系统,以便我可以轻松地将它发送到后端。
第一笔或第二笔 运行 没问题,但之后,它使用了大量的 CPU 循环并且无法使用。
你们能发挥你们的魔力并告诉我如何改进它吗?
我删除了大部分无用的东西:
from tkinter import Tk, Canvas, NW, NE, N
fen = Tk()
fen.geometry("1380x740")
fen.title("Dessine moi un mouton !")
c_width = 800
c_height = 600
couleur = "red"
epaisseur= 10
sdessin = Canvas(width = c_width, height = c_height, bg ='white')
board = []
for i in range(0, c_width, 10):
board.append(["white" for j in range(0, c_height, 10)])
#board[4][7] = "red"
def pix_to_units(x, y):
if x > 10 and y > 10:
i = int(str(x)[:-1])
j = int(str(y)[:-1])
return i-1,j-1
else:
return 0, 0
def afficher_dessin(): #display board
for i in range(len(board)):
b = board[i]
for j in range(len(b)):
if b[j] != sdessin["background"]:
sdessin.create_rectangle(i*10, j*10,i*10+10, j*10+10, fill = b[j], outline = b[j])
def draw():
afficher_dessin()
fen.after(200, draw)
def interaction(coords):
i, j = pix_to_units(coords.x, coords.y)
board[i][j] = couleur
sdessin.bind("<B1-Motion>", interaction)
sdessin.grid(row =2, column =2, sticky=N)
draw()
fen.mainloop()
您在每次更新中都创建了新的矩形项,这是 CPU 使用率高的原因,没有必要。只需创建一次矩形项目并在 iteraction()
函数中更新它们的颜色,无需使用 after()
更新面板。
以下是基于您的代码的简化代码:
from tkinter import Tk, Canvas, NW, NE, N
fen = Tk()
fen.geometry("1380x740")
fen.title("Dessine moi un mouton !")
c_width = 800
c_height = 600
couleur = "red"
epaisseur= 10
sdessin = Canvas(width = c_width, height = c_height, bg ='white')
rows, cols = c_height//10, c_width//10
# create the board
board = [['white' for _ in range(cols)] for _ in range(rows)]
# draw the board
for row in range(rows):
for col in range(cols):
x, y = col*10, row*10
sdessin.create_rectangle(x, y, x+10, y+10, fill=board[row][col], outline='',
tag='%d:%d'%(row,col)) # tag used for updating color later
def pix_to_units(x, y):
return y//10, x//10 # row, col
def interaction(event):
row, col = pix_to_units(event.x, event.y)
board[row][col] = couleur
tag = '%d:%d' % (row, col)
sdessin.itemconfig(tag, fill=couleur)
sdessin.bind("<B1-Motion>", interaction)
sdessin.grid(row=2, column=2, sticky=N)
fen.mainloop()
我一直在研究类似 Tkinter "Paint" 的程序,但我遇到了性能问题。我不得不设置 200 毫秒的延迟来重绘,因为没有它它真的 运行。它必须使用这个网格系统,以便我可以轻松地将它发送到后端。
第一笔或第二笔 运行 没问题,但之后,它使用了大量的 CPU 循环并且无法使用。
你们能发挥你们的魔力并告诉我如何改进它吗?
我删除了大部分无用的东西:
from tkinter import Tk, Canvas, NW, NE, N
fen = Tk()
fen.geometry("1380x740")
fen.title("Dessine moi un mouton !")
c_width = 800
c_height = 600
couleur = "red"
epaisseur= 10
sdessin = Canvas(width = c_width, height = c_height, bg ='white')
board = []
for i in range(0, c_width, 10):
board.append(["white" for j in range(0, c_height, 10)])
#board[4][7] = "red"
def pix_to_units(x, y):
if x > 10 and y > 10:
i = int(str(x)[:-1])
j = int(str(y)[:-1])
return i-1,j-1
else:
return 0, 0
def afficher_dessin(): #display board
for i in range(len(board)):
b = board[i]
for j in range(len(b)):
if b[j] != sdessin["background"]:
sdessin.create_rectangle(i*10, j*10,i*10+10, j*10+10, fill = b[j], outline = b[j])
def draw():
afficher_dessin()
fen.after(200, draw)
def interaction(coords):
i, j = pix_to_units(coords.x, coords.y)
board[i][j] = couleur
sdessin.bind("<B1-Motion>", interaction)
sdessin.grid(row =2, column =2, sticky=N)
draw()
fen.mainloop()
您在每次更新中都创建了新的矩形项,这是 CPU 使用率高的原因,没有必要。只需创建一次矩形项目并在 iteraction()
函数中更新它们的颜色,无需使用 after()
更新面板。
以下是基于您的代码的简化代码:
from tkinter import Tk, Canvas, NW, NE, N
fen = Tk()
fen.geometry("1380x740")
fen.title("Dessine moi un mouton !")
c_width = 800
c_height = 600
couleur = "red"
epaisseur= 10
sdessin = Canvas(width = c_width, height = c_height, bg ='white')
rows, cols = c_height//10, c_width//10
# create the board
board = [['white' for _ in range(cols)] for _ in range(rows)]
# draw the board
for row in range(rows):
for col in range(cols):
x, y = col*10, row*10
sdessin.create_rectangle(x, y, x+10, y+10, fill=board[row][col], outline='',
tag='%d:%d'%(row,col)) # tag used for updating color later
def pix_to_units(x, y):
return y//10, x//10 # row, col
def interaction(event):
row, col = pix_to_units(event.x, event.y)
board[row][col] = couleur
tag = '%d:%d' % (row, col)
sdessin.itemconfig(tag, fill=couleur)
sdessin.bind("<B1-Motion>", interaction)
sdessin.grid(row=2, column=2, sticky=N)
fen.mainloop()