我不能在 tkinter 中用 after() 重复我的功能
I cannot repeat my function with after() in tkinter
我在使用格气自动机应用程序时遇到问题。好吧,我无法使用 after() 函数刷新图像。应用程序正在启动,没有其他事情发生。我已经尝试过许多使用这种方法或任何其他方法每隔一段时间重复自动机但没有成功的组合。你能帮我解决这个问题吗?
第一个文件:
from PIL import Image, ImageTk
import tkinter as tk
import numpy as np
import methods
class Window:
def __init__(self, master):
self.master = master
self.frame = tk.Frame(self.master, background="white")
self.img_matrix = np.zeros([600, 600, 3], dtype=np.uint8)
self.state_matrix = np.zeros([600, 600, 5], dtype=np.uint8)
self.img_matrix, self.state_matrix = methods.fill_matrix(self.img_matrix, self.state_matrix)
self.img = ImageTk.PhotoImage(image=Image.fromarray(self.img_matrix))
self.canvas = tk.Canvas(self.frame, width=600, height=600)
self.canvas.pack(side="left", fill="y")
self.canvas.create_image(0, 0, anchor="nw", image=self.img)
self.frame.pack()
self.master.after(1000, methods.simulate(self.canvas, self.img_matrix, self.state_matrix))
def main():
root = tk.Tk()
root.withdraw()
top = tk.Toplevel(root)
top.protocol("WM_DELETE_WINDOW", root.destroy)
app = Window(top)
top.title("LGA")
top.mainloop()
if __name__ == '__main__':
main()
第二个:
import numba
from numba import jit, njit
from PIL import Image, ImageTk
import numpy as np
import random
@jit(nopython=True, parallel=True)
def fill_matrix(img_matrix, state_matrix):
for x in numba.prange(0, state_matrix.shape[0]-1):
for y in numba.prange(0, state_matrix.shape[1]-1):
state = state_matrix[x, y]
if y == 0 or x == 0 or y == state_matrix.shape[1]-1 or x == state_matrix.shape[0]-1:
state[0] = 1
state_matrix[x, y] = state
img_matrix[x, y] = [255, 255, 255]
if y == 150 and (0 < x < (((state_matrix.shape[0]-1)/2)-25) or \
(((state_matrix.shape[0]-1)/2)+25 < x < state_matrix.shape[0]-1)):
state[0] = 1
state_matrix[x, y] = state[0]
img_matrix[x, y] = [255, 255, 255]
random_gen_1 = random.randint(0, 100)
treshold = 92
if 0 < y < 150 and 0 < x < (state_matrix.shape[0]-1) and random_gen_1 > treshold:
random_gen_2 = random.randint(1, 4)
if random_gen_2 == 1:
state[1] = 1
elif random_gen_2 == 2:
state[2] = 1
elif random_gen_2 == 3:
state[3] = 1
elif random_gen_2 == 4:
state[4] = 1
state_matrix[x, y] = state
img_matrix[x, y] = [255, 0, 0]
return img_matrix, state_matrix
def simulate(canvas, img_matrix, state_matrix):
new_state_matrix = np.zeros([state_matrix.shape[0], state_matrix.shape[1], 5], dtype=np.uint8)
new_img_matrix = np.zeros([state_matrix.shape[0], state_matrix.shape[1], 3], dtype=np.uint8)
new_state_matrix, new_img_matrix = state_sim(state_matrix, new_state_matrix, img_matrix, new_img_matrix)
img = ImageTk.PhotoImage(image=Image.fromarray(new_img_matrix))
canvas.create_image(0, 0, anchor="nw", image=img)
#return img, new_img_matrix, new_state_matrix
@jit(nopython=True, parallel=True)
def state_sim(state_matrix, new_state_matrix, img_matrix, new_img_matrix):
for x in numba.prange(0, state_matrix.shape[0]-1):
for y in numba.prange(0, state_matrix.shape[1]-1):
state = state_matrix[x, y]
if state[0] == 1:
new_state_matrix[x, y] = state_matrix[x, y] #[1, 0, 0, 0, 0]
new_img_matrix[x, y] = img_matrix[x, y] #[255, 255, 255]
else:
new_state = state
state_up = state_matrix[x - 1, y]
state_right = state_matrix[x, y + 1]
state_down = state_matrix[x + 1, y]
state_left = state_matrix[x, y - 1]
new_state_up = state_matrix[x - 1, y]
new_state_right = state_matrix[x, y + 1]
new_state_down = state_matrix[x + 1, y]
new_state_left = state_matrix[x, y - 1]
#state
if state_up[3] == 1:
new_state[1] = 1
new_state_up[3] = 0
if state_right[4] == 1:
new_state[2] = 1
new_state_right[4] = 0
if state_down[1] == 1:
new_state[3] = 1
new_state_down[1] = 0
if state_left[2] == 1:
new_state[4] = 1
new_state_left[2] = 0
if new_state[1] == 1 and new_state[3] == 1:
new_state[1] = 0
new_state[2] = 1
new_state[3] = 0
new_state[4] = 1
elif new_state[2] == 1 and new_state[4] == 1:
new_state[1] = 1
new_state[2] = 0
new_state[3] = 1
new_state[4] = 0
new_state_matrix[x, y] = new_state
if new_state[1] == 1 or new_state[2] == 1 or new_state[3] == 1 or new_state[4] == 1:
new_img_matrix[x, y] = [255, 0, 0]
return new_state_matrix, new_img_matrix
为什么 simulate() 函数不会每隔一段时间重复一次?感谢您的回答!
要使用after,你必须传递函数引用。假设我有一个函数 hi()
只在屏幕上打印“hi”。如果我在给 after()
参数时 调用 hi,那么我会传递 hi()
的 return 值作为参数:.after(200, hi()) # hi() is equal to None
.相反,我应该这样传递参考:.after(200, hi)
.
但是,您不能这样做,因为您需要将参数传递给函数。为此,您可以使用 lambda
创建一个匿名函数,该函数使用其参数调用您的函数:.after(200, lambda: methods.simulate(self.canvas, self.img_matrix, self.state_matrix))
.
我在使用格气自动机应用程序时遇到问题。好吧,我无法使用 after() 函数刷新图像。应用程序正在启动,没有其他事情发生。我已经尝试过许多使用这种方法或任何其他方法每隔一段时间重复自动机但没有成功的组合。你能帮我解决这个问题吗?
第一个文件:
from PIL import Image, ImageTk
import tkinter as tk
import numpy as np
import methods
class Window:
def __init__(self, master):
self.master = master
self.frame = tk.Frame(self.master, background="white")
self.img_matrix = np.zeros([600, 600, 3], dtype=np.uint8)
self.state_matrix = np.zeros([600, 600, 5], dtype=np.uint8)
self.img_matrix, self.state_matrix = methods.fill_matrix(self.img_matrix, self.state_matrix)
self.img = ImageTk.PhotoImage(image=Image.fromarray(self.img_matrix))
self.canvas = tk.Canvas(self.frame, width=600, height=600)
self.canvas.pack(side="left", fill="y")
self.canvas.create_image(0, 0, anchor="nw", image=self.img)
self.frame.pack()
self.master.after(1000, methods.simulate(self.canvas, self.img_matrix, self.state_matrix))
def main():
root = tk.Tk()
root.withdraw()
top = tk.Toplevel(root)
top.protocol("WM_DELETE_WINDOW", root.destroy)
app = Window(top)
top.title("LGA")
top.mainloop()
if __name__ == '__main__':
main()
第二个:
import numba
from numba import jit, njit
from PIL import Image, ImageTk
import numpy as np
import random
@jit(nopython=True, parallel=True)
def fill_matrix(img_matrix, state_matrix):
for x in numba.prange(0, state_matrix.shape[0]-1):
for y in numba.prange(0, state_matrix.shape[1]-1):
state = state_matrix[x, y]
if y == 0 or x == 0 or y == state_matrix.shape[1]-1 or x == state_matrix.shape[0]-1:
state[0] = 1
state_matrix[x, y] = state
img_matrix[x, y] = [255, 255, 255]
if y == 150 and (0 < x < (((state_matrix.shape[0]-1)/2)-25) or \
(((state_matrix.shape[0]-1)/2)+25 < x < state_matrix.shape[0]-1)):
state[0] = 1
state_matrix[x, y] = state[0]
img_matrix[x, y] = [255, 255, 255]
random_gen_1 = random.randint(0, 100)
treshold = 92
if 0 < y < 150 and 0 < x < (state_matrix.shape[0]-1) and random_gen_1 > treshold:
random_gen_2 = random.randint(1, 4)
if random_gen_2 == 1:
state[1] = 1
elif random_gen_2 == 2:
state[2] = 1
elif random_gen_2 == 3:
state[3] = 1
elif random_gen_2 == 4:
state[4] = 1
state_matrix[x, y] = state
img_matrix[x, y] = [255, 0, 0]
return img_matrix, state_matrix
def simulate(canvas, img_matrix, state_matrix):
new_state_matrix = np.zeros([state_matrix.shape[0], state_matrix.shape[1], 5], dtype=np.uint8)
new_img_matrix = np.zeros([state_matrix.shape[0], state_matrix.shape[1], 3], dtype=np.uint8)
new_state_matrix, new_img_matrix = state_sim(state_matrix, new_state_matrix, img_matrix, new_img_matrix)
img = ImageTk.PhotoImage(image=Image.fromarray(new_img_matrix))
canvas.create_image(0, 0, anchor="nw", image=img)
#return img, new_img_matrix, new_state_matrix
@jit(nopython=True, parallel=True)
def state_sim(state_matrix, new_state_matrix, img_matrix, new_img_matrix):
for x in numba.prange(0, state_matrix.shape[0]-1):
for y in numba.prange(0, state_matrix.shape[1]-1):
state = state_matrix[x, y]
if state[0] == 1:
new_state_matrix[x, y] = state_matrix[x, y] #[1, 0, 0, 0, 0]
new_img_matrix[x, y] = img_matrix[x, y] #[255, 255, 255]
else:
new_state = state
state_up = state_matrix[x - 1, y]
state_right = state_matrix[x, y + 1]
state_down = state_matrix[x + 1, y]
state_left = state_matrix[x, y - 1]
new_state_up = state_matrix[x - 1, y]
new_state_right = state_matrix[x, y + 1]
new_state_down = state_matrix[x + 1, y]
new_state_left = state_matrix[x, y - 1]
#state
if state_up[3] == 1:
new_state[1] = 1
new_state_up[3] = 0
if state_right[4] == 1:
new_state[2] = 1
new_state_right[4] = 0
if state_down[1] == 1:
new_state[3] = 1
new_state_down[1] = 0
if state_left[2] == 1:
new_state[4] = 1
new_state_left[2] = 0
if new_state[1] == 1 and new_state[3] == 1:
new_state[1] = 0
new_state[2] = 1
new_state[3] = 0
new_state[4] = 1
elif new_state[2] == 1 and new_state[4] == 1:
new_state[1] = 1
new_state[2] = 0
new_state[3] = 1
new_state[4] = 0
new_state_matrix[x, y] = new_state
if new_state[1] == 1 or new_state[2] == 1 or new_state[3] == 1 or new_state[4] == 1:
new_img_matrix[x, y] = [255, 0, 0]
return new_state_matrix, new_img_matrix
为什么 simulate() 函数不会每隔一段时间重复一次?感谢您的回答!
要使用after,你必须传递函数引用。假设我有一个函数 hi()
只在屏幕上打印“hi”。如果我在给 after()
参数时 调用 hi,那么我会传递 hi()
的 return 值作为参数:.after(200, hi()) # hi() is equal to None
.相反,我应该这样传递参考:.after(200, hi)
.
但是,您不能这样做,因为您需要将参数传递给函数。为此,您可以使用 lambda
创建一个匿名函数,该函数使用其参数调用您的函数:.after(200, lambda: methods.simulate(self.canvas, self.img_matrix, self.state_matrix))
.