我在晶格气体自动机应用程序的工作中遇到了一个问题。嗯,我不能用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,必须传递函数引用。假设我有一个函数CCD_ 1;嗨"到屏幕。如果我在为after()
提供参数时调用hi,那么我将传递hi()
的返回值作为参数:.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))
。