尝试在 tkinter mainloop 旁边运行一个 while true 循环

Posted

技术标签:

【中文标题】尝试在 tkinter mainloop 旁边运行一个 while true 循环【英文标题】:Trying to run a while true loop alongside tkinter mainloop 【发布时间】:2021-08-31 10:25:18 【问题描述】:

我正在尝试用 4 个进程编写一个生命游戏,每个进程处理四分之一的细胞。 这是我的问题: 我使用 tkinter 的画布来显示单元格,我必须运行一个 while true 循环来更新它旁边的单元格,但我不知道该怎么做。

下面是我的完整代码: 显示函数是我需要同时运行 tkinter 主循环和具有 while true 循环的 canvas_fill 函数的地方。

其他功能如下:

种子产生第一批活细胞 管理每个子网格的mini_grid
from tkinter import * 
import multiprocessing as mp
import time

#matrix size
size = 20
#seed
x_table = [7,7,8,8,8,9]
y_table = [4,5,4,5,6,6]

def display(Cells,window,PipeA):
    #i,j,alive

    canvas = Canvas(window,height='400',width='400')
    canvas.pack()
    
    window.mainloop()
    canvas_fill(Cells,window,PipeA,canvas)
    

def canvas_fill(Cells, window, PipeA, canvas):
    while True:
        print("looping")
        [i,j,alive]=PipeA.recv()
        x= (i*20)-20
        y= (j*20)-20
        if alive == 0:
            Cells[((i*size)+j)%(size**2)]=0
            canvas.create_rectangle(x,y,x+20,y+20,fill='white')
        else:
            Cells[((i*size)+j)%(size**2)]=1
            print("case vivante crée")
            canvas.create_rectangle(x,y,x+20,y+20,fill='lime green')

def seed(Cells,lock,PipeB):
    for i in range(len(x_table)):
        with lock:
            fill_cell(x_table[i],y_table[i],1,Cells,lock)
            #envoyer par pipe
            PipeB.send((x_table[i],y_table[i],1))


def mini_grid(id,Cells,lock,PipeB):
    near = [-1,-9,-10,-11,+1,+9,+10,+11]
    z=0
    while z<10:
        z+=1
        for i in range(int(size*size/4)):
            n=i//size #ligne n
            p=i%size # colonne p
            if id==1:
                p=p+size
            if id==2:
                n=n+size
            if id==3:
                n=n+size
                p=p+size
            cells_alive_around = 0
            for j in near:
                if Cells[((n*size)+p+j)%(size*size)]==1:
                    cells_alive_around +=1
            if Cells[((n*size)+p)%(size**2)] == 0:
                #cellule morte
                if cells_alive_around == 3:
                    #devient vivante
                    PipeB.send((n,p,1))
                    Cells[(n*size+p)%(size**2)]=1
            else:
                #cellule vivante
                if cells_alive_around <2 or cells_alive_around >3:
                    #devient morte
                    PipeB.send((n,p,0))
                    print(n*size+p)
                    print('n ',n)
                    Cells[(n*size+p)%(size**2)]=0
        time.sleep(2)

if __name__ == "__main__" :
    size = 10*10 # grille 20*20 donc 4 sous-grilles 10*10
    window = Tk()
    window.title("Game of life")

    lock = mp.Lock()
    Cells = mp.Array('i',[0]*size**2)
    Grids = [0,0,0,0]

    PipeA,PipeB = mp.Pipe()
    Display = mp.Process(target = display,args=(Cells,window,PipeA))
    Display.start()
    seed(Cells,lock,PipeB)
    for i in range(4): #Création des 4 sous grilles
        Grids[i] = mp.Process(target= mini_grid,args=(i,Cells,lock,PipeB))
        Grids[i].start()

【问题讨论】:

【参考方案1】:

好吧,我发现我可以使用 window.update() 在我的 while 循环中,而不是 mainloop()

【讨论】:

【参考方案2】:

我相信您需要将 canvas_fill() 函数设置为按节奏运行。尝试实施此处找到的解决方案。 tkinter root.mainloop with While True loop

我不是这里的专家,但我希望这至少能让你走上正确的道路。

【讨论】:

以上是关于尝试在 tkinter mainloop 旁边运行一个 while true 循环的主要内容,如果未能解决你的问题,请参考以下文章

关于Tkinter的几个问题——mainloop、更新方法、有效性等

如何在另一个任务旁边运行 tkinter 的 after event?

如何在 tkinter 旁边运行循环? - Python 二维码阅读器图形用户界面

Python:Tkinter:为啥是 root.mainloop() 而不是 app.mainloop()

Tkinter 理解 mainloop

你如何在Tkinter的事件循环中运行自己的代码?