Я не могу повторить свою функцию с after() в 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

Почему функция симуляции() не повторяется каждый раз? Спасибо за ответы!

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
201
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Чтобы использовать after, вы должны передать ссылку на функцию. Допустим, у меня есть функция hi(), которая просто выводит «привет» на экран. Если я вызову hi при передаче аргументов after(), то я передам возвращаемое значение 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)).

Вам не нужно lambda передавать позиционные аргументы с помощью after. Это будет работать и будет немного легче читать: self.master.after(1000, methods.simulate, self.canvas, self.img_matrix, self.state_matrix)

Bryan Oakley 14.12.2020 23:11

@BryanOakley Я не знал об этом, спасибо, это все еще полезно знать, например, если вы хотите передать аргументы функции, когда вы назначаете ее, например, command= в кнопке.

tralph3 14.12.2020 23:41

Другие вопросы по теме