我不能在tkinter中用after()重复我的函数

2024-04-20 07:45:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我在使用晶格气自动机应用程序时遇到问题。嗯,我不能用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()函数不会每隔一段时间重复一次?谢谢你的回答


Tags: orimageimportselfimgnewifnp
1条回答
网友
1楼 · 发布于 2024-04-20 07:45:58

要使用after,必须传递函数引用。假设我有一个函数hi(),它只在屏幕上打印“hi”。如果我在给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))

相关问题 更多 >