如何让我的功能与另一个功能不同时工作?

时间:2018-06-05 17:45:14

标签: python tkinter

我正在尝试创造一个运气游戏,你必须在3个门后面挑选2个相同颜色的球,然后你尝试3个,每个门有1个球,我在你打开一扇门时被挡住了我想在门展示球和球消失的那一刻之间做出延迟。我已经尝试使用time.sleep,但它在显示时运行睡眠。这是我的代码:

import tkinter as tk
import tkinter as tk
from random import shuffle
import time
fenetre = tk.Tk()
fenetre['bg']='black'
fenetre.geometry("1152x768")
color = ["red", "green", "yellow"]
shuffle(color)

frameGauche = tk.Frame(width=200, height=600, bg='pink')
frameGauche.grid(row=0, column=0, padx=10, pady=10)

frameDroite = tk.Frame(width=700, height=700, bg='grey')
frameDroite.grid(row=0, column=1, padx=10, pady=10)

portegauche=tk.Frame(frameDroite, width=200, 
height=600,bg='white',bd=5,relief='groove')
portegauche.grid(row=0, column=0, padx=5, pady=5)

portemilieu=tk.Frame(frameDroite, width=200, 
height=600,bg='white',bd=5,relief='groove')
portemilieu.grid(row=0, column=1, padx=5, pady=5)

portedroite=tk.Frame(frameDroite, width=200, 
height=600,bg='white',bd=5,relief='groove')
portedroite.grid(row=0, column=2, padx=5, pady=5)

def show1(canvas1, bouton2, bouton3):
    canvas1.grid(row=0, column=1)
    bouton2['state']='disabled'
    bouton3['state']='disabled'
    time.sleep(2)
    bouton2['state']='normal'
    bouton3['state']='normal'
    canvas1.grid_remove()
def show2():
    canvas2.grid(row=0, column=2)
    bouton1['state']='disabled'
    bouton3['state']='disabled'
    time.sleep(2)
    bouton1['state']='normal'
    bouton3['state']='normal'
    canvas2.grid_remove()
def show3():
    canvas3.grid(row=0, column=3)
    bouton2['state']='disabled'
    bouton1['state']='disabled'
    time.sleep(2)
    bouton2['state']='normal'
    bouton1['state']='normal'
    canvas3.grid_remove()

canvas1=tk.Canvas(portegauche,width=200, height=600, bg='white')
c1 = canvas1.create_oval((60,280), (140,340), width=1, outline="black", 
fill=color[0])
canvas1.grid_forget()

canvas2=tk.Canvas(portemilieu,width=200, height=600, bg='white')
c2 = canvas2.create_oval((60,280), (140,340), width=1, outline="black", 
fill=color[1])
canvas2.grid_forget()

canvas3=tk.Canvas(portedroite,width=200, height=600, bg='white')
c3 = canvas3.create_oval((60,280), (140,340), width=1, outline="black", 
fill=color[2])
canvas3.grid_forget()

def recommencer():
    canvas1.grid_remove()
    canvas2.grid_remove()
    canvas3.grid_remove()
    shuffle(color)
    canvas1.create_oval((60,280), (140,340), width=1, outline="black", fill=color[0])
    canvas2.create_oval((60,280), (140,340), width=1, outline="black", fill=color[1])
    canvas3.create_oval((60,280), (140,340), width=1, outline="black", fill=color[2])
    bouton1['state']='normal'
    bouton2['state']='normal'
    bouton3['state']='normal'

boutonR = tk.Button(frameGauche, text='Recommencer',command=recommencer)
boutonR.grid(row=0, column=0, padx=50, pady=50)

bouton1=tk.Button(frameDroite, text= 'Ouvrir',command=lambda: show1(canvas1, 
bouton2, bouton3))
bouton1.grid(row=1, column=0)

bouton2=tk.Button(frameDroite, text= 'Ouvrir',command=show2)
bouton2.grid(row=1, column=1)

bouton3=tk.Button(frameDroite, text= 'Ouvrir',command=show3)
bouton3.grid(row=1, column=2)

fenetre.mainloop()

2 个答案:

答案 0 :(得分:2)

如前所述,sleep()将冻结执行,在GUI编程中绝不是一个好主意。

为了让这个工作分解你的showx函数显示和隐藏,这里是show1的一个例子。这里我们使用.after调用lambda函数(这使得传递参数更容易),.after的第一个参数是以毫秒为单位的时间

def show1(canvas1, bouton2, bouton3):
    canvas1.grid(row=0, column=1)
    bouton2['state']='disabled'
    bouton3['state']='disabled'
    # OLD fenetre.after(2000, lambda: hide1(canvas1, bouton2, bouton3))
    # New thanks to Mike-SMT
    fenetre.after(2000, hide1, canvas1, bouton2, bouton3)

def hide1(canvas1, bouton2, bouton3):
    bouton2['state']='normal'
    bouton3['state']='normal'
    canvas1.grid_remove()

这里的答案我从中得到了一些细节 Tkinter after

[编辑] 你可以通过创建一个show和一个hide函数并将canvas / button对象作为参数传递来简化这一过程,从长远来看,还有更多的重构可以使这个更简单,但是为了让你开始使用.after()应该是你现在所需要的。

您可能想要删除文件顶部的双重导入

import tkinter as tk

答案 1 :(得分:2)

主要问题是您使用sleep()。在tkinter中休眠会导致整个实例冻结,并且无法按预期工作。相反,您可以使用after()

您还要两次导入tkinter。删除tkinter的导入。

那就是说我们需要添加一个新函数并在函数中更改几行。

我添加了一个名为normalize_button()的函数,它为按钮名称取一个参数。这与after()方法一起使用,以在2秒后更新按钮。

在评论中回答你的问题:

{2}过后,normalize_button()方法调用函数after()。该方法检查传递给它的字符串,并根据该字符串更新按钮。实际上,您可以使用show方法执行相同的操作,并且只需一种方法即可更新所有按钮。它让事情变得更清洁,并遵循DRY(不要重复自己)PEP8风格。

看看下面的代码。

import tkinter as tk
from random import shuffle

fenetre = tk.Tk()
fenetre['bg']='black'
fenetre.geometry("1152x768")
color = ["red", "green", "yellow"]
shuffle(color)

frameGauche = tk.Frame(width=200, height=600, bg='pink')
frameGauche.grid(row=0, column=0, padx=10, pady=10)

frameDroite = tk.Frame(width=700, height=700, bg='grey')
frameDroite.grid(row=0, column=1, padx=10, pady=10)

portegauche=tk.Frame(frameDroite, width=200, 
height=600,bg='white',bd=5,relief='groove')
portegauche.grid(row=0, column=0, padx=5, pady=5)

portemilieu=tk.Frame(frameDroite, width=200, 
height=600,bg='white',bd=5,relief='groove')
portemilieu.grid(row=0, column=1, padx=5, pady=5)

portedroite=tk.Frame(frameDroite, width=200, 
height=600,bg='white',bd=5,relief='groove')
portedroite.grid(row=0, column=2, padx=5, pady=5)

def normalize_button(btn_name):
    print(btn_name)
    if btn_name == "b1":
        bouton1['state']='normal'
    if btn_name == "b2":
        bouton2['state']='normal'
    if btn_name == "b3":
        bouton3['state']='normal'

def show1():
    canvas1.grid(row=0, column=1)
    bouton2['state']='disabled'
    bouton3['state']='disabled'
    fenetre.after(2000, normalize_button, "b2")
    fenetre.after(2000, normalize_button, "b3")
    fenetre.after(2000, canvas1.grid_forget)

def show2():
    canvas2.grid(row=0, column=2)
    bouton1['state']='disabled'
    bouton3['state']='disabled'
    fenetre.after(2000, normalize_button, "b1")
    fenetre.after(2000, normalize_button, "b3")
    fenetre.after(2000, canvas2.grid_forget)

def show3():
    canvas3.grid(row=0, column=3)
    bouton2['state']='disabled'
    bouton1['state']='disabled'
    fenetre.after(2000, normalize_button, "b2")
    fenetre.after(2000, normalize_button, "b1")
    fenetre.after(2000, canvas3.grid_forget)

canvas1 = tk.Canvas(portegauche,width=200, height=600, bg='white')
c1 = canvas1.create_oval((60,280), (140,340), width=1, outline="black", fill=color[0])
canvas1.grid_forget()

canvas2 = tk.Canvas(portemilieu,width=200, height=600, bg='white')
c2 = canvas2.create_oval((60,280), (140,340), width=1, outline="black", fill=color[1])
canvas2.grid_forget()

canvas3 = tk.Canvas(portedroite,width=200, height=600, bg='white')
c3 = canvas3.create_oval((60,280), (140,340), width=1, outline="black", fill=color[2])
canvas3.grid_forget()

def recommencer():
    canvas1.grid_remove()
    canvas2.grid_remove()
    canvas3.grid_remove()
    shuffle(color)
    canvas1.create_oval((60,280), (140,340), width=1, outline="black", fill=color[0])
    canvas2.create_oval((60,280), (140,340), width=1, outline="black", fill=color[1])
    canvas3.create_oval((60,280), (140,340), width=1, outline="black", fill=color[2])
    bouton1['state']='normal'
    bouton2['state']='normal'
    bouton3['state']='normal'

boutonR = tk.Button(frameGauche, text='Recommencer',command=recommencer)
boutonR.grid(row=0, column=0, padx=50, pady=50)

bouton1=tk.Button(frameDroite, text= 'Ouvrir',command=show1)
bouton1.grid(row=1, column=0)

bouton2=tk.Button(frameDroite, text= 'Ouvrir',command=show2)
bouton2.grid(row=1, column=1)

bouton3=tk.Button(frameDroite, text= 'Ouvrir',command=show3)
bouton3.grid(row=1, column=2)

fenetre.mainloop()