所以我在写我的第一个真正的程序的中间,我似乎找不到一个解决方案。我希望能够单击多个标签在不同的时间与停止以前的标签,当一个新的被点击。起初,这对我来说似乎是一个简单的问题,但在阅读后,我相信它比我想象的更复杂。异步代码能解决我的问题吗?如果不是,什么会?Btw代码编译和工作很好,除了我明显的问题。
from Tkinter import *
import os
import time
class League_Jungle_Timer(Frame):
def __init__(self):
Frame.__init__(self)
self.master.title("Jungle Timer by BabyAchilles") # initializes window
self.master.geometry("550x300")
self.pack(expand = YES, fill = BOTH)
self.Label1 = Label(self)
self.Label1 = Label(text = "Blue Buff") #--------------> #Start Tkinter GUI Labels
self.Label1.pack()
self.Label2 = Label(self)
self.Label2 = Label(self, text = "Red Buff")
self.Label2.pack()
self.Label3=Label(self)
self.Label3=Label(self, text = "Dragon",font=("Helvetica", 16))
self.Label3.pack()
self.Button1 = Button(self) #--------------> #Start Tkinter GUI Buttons
self.Button1["text"] = "Blue Buff"
self.Button1["fg"] = "Blue"
self.Button1["command"] = self.label_clicked
self.Button1.pack({"side": "left"})
self.Button2 = Button(self)
self.Button2["text"] = "Red Buff"
self.Button2["fg"] = "Red"
self.Button2["command"] = self.my_timeRB
self.Button2.pack({"side":"right"})
self.Button2.pack(padx=50)
self.Button3 = Button(self)
self.Button3["text"] = " Dragon "
self.Button3["fg"] = "Pink"
self.Button3["bg"] = "Purple"
self.Button3["command"] = self.my_timeDrag
self.Button3.pack(side="bottom",pady=50)
self.Quit = Button(self)
self.Quit["text"] = "Quit"
self.Quit["command"] = self.destroy
self.Quit.pack()
self.Label1.bind("<Button-1>", self.label_clicked)
self.Label2.bind("<Button-3>", self.label2_clicked)
self.Label3.bind("<Double-Button-1>",self.label3_clicked)
##########################################################################
def my_timeDrag(self): # creates a timer starting at 5 min , counts down to 0 then repeats
min_m = 5
sec = 59
while sec <=60:
self.Label3.configure(text="{0}:{1:02}".format(min_m, sec))
self.Label3.update()
os.system('cls')
print min_m, "Minutes", sec, "Seconds"
time.sleep(1)
sec -= 1
if sec == 0:
min_m -= 1
sec = 59
elif min_m == 0:
min_m = 5
##########################################################################################
def my_timeBB(self): # creates a timer starting at 5 min , counts down to 0 then repeats
min_m = 4
sec = 59
while sec <=60:
self.Label1.configure(text="{0}:{1:02}".format(min_m,sec))
self.Label1.update()
os.system('cls')
print min_m, "Minutes", sec, "Seconds"
time.sleep(1)
sec -= 1
if sec == 0:
min_m -= 1
sec = 59
elif min_m == 0:
min_m = 4
#######################################################
def my_timeRB(self): # creates a timer starting at 5 min , counts down to 0 then repeats
_min = 4
sec = 59
while sec <=60:
self.Label2.configure(text="{0}:{1:02}".format(_min,sec))
self.Label2.update()
os.system('cls')
print _min, "Minutes", sec, "Seconds"
time.sleep(1)
sec -= 1
if sec == 0:
_min -= 1
sec = 59
elif _min == 0:
_min = 4
##############################################################
def label_clicked(self, event):
self.Label1.configure(self.my_timeBB())
self.Label1.update()
def label2_clicked(self, event):
self.Label2.configure(self.my_timeRB())
self.Label2.update()
def label3_clicked(self, even):
self.Label3.configure(self.my_timeDrag())
self.Label3.update()
League_Jungle_Timer().mainloop()
您可以使用tk.after()
来获取这个
使用after(1000, function_name)
,您在1000 ms后运行一些(小)函数,它不会停止其他函数(如果您不使用time.sleep
)。这个功能可以让after()
自己再次运行。
from Tkinter import *
import os
import time
class League_Jungle_Timer(Frame):
def __init__(self):
Frame.__init__(self)
# initializes window
self.master.title("Jungle Timer by BabyAchilles")
self.master.geometry("550x300")
self.pack(expand=YES, fill=BOTH)
# Start Tkinter GUI Labels
self.label1 = Label(self, text="Blue Buff")
self.label1.pack()
self.label2 = Label(self, text="Red Buff")
self.label2.pack()
self.label3=Label(self, text="Dragon", font=("Helvetica", 16))
self.label3.pack()
# Start Tkinter GUI Buttons
self.Button1 = Button(self, text="Blue Buff", fg="Blue", command=self.my_timeBB)
self.Button1.pack(side="left")
self.Button2 = Button(self, text="Red Buff", fg="Red", command=self.my_timeRB)
self.Button2.pack(side="right", padx=50)
self.Button3 = Button(self, text=" Dragon ", fg="Pink", bg="Purple", command=self.my_timeDrag)
self.Button3.pack(side="bottom",pady=50)
self.Quit = Button(self, text="Quit", command=self.destroy)
self.Quit.pack()
self.label1.bind("<Button-1>", self.label_clicked)
self.label2.bind("<Button-3>", self.label2_clicked)
self.label3.bind("<Double-Button-1>",self.label3_clicked)
self.timer_id_DR = None
self.timer_id_RB = None
self.timer_id_BB = None
#######################################################
# creates a timer starting at 5 min , counts down to 0 then repeats
def my_timeDrag(self):
self.my_timeDrag_time = [4, 59]
if self.timer_id_DR:
self.after_cancel(self.timer_id_DR)
self.timer_id_DR = None
self.my_timeDrag_after()
def my_timeDrag_after(self):
m, s = self.my_timeDrag_time
self.label3.configure(text="{0}:{1:02}".format(m, s))
self.label3.update()
#os.system('cls')
print "DR", m, "Minutes", s, "Seconds"
s -= 1
if s == 0:
m -= 1
s = 59
elif m == 0:
m = 5
self.my_timeDrag_time = [m, s]
self.timer_id_DR = self.after(1000, self.my_timeDrag_after)
#######################################################
# creates a timer starting at 5 min , counts down to 0 then repeats
def my_timeBB(self):
self.my_timeBB_time = [4, 59]
if self.timer_id_BB:
self.after_cancel(self.timer_id_BB)
self.timer_id_BB = None
self.my_timeBB_after()
def my_timeBB_after(self):
m, s = self.my_timeBB_time
self.label1.configure(text="{0}:{1:02}".format(m, s))
self.label1.update()
#os.system('cls')
print "BB", m, "Minutes", s, "Seconds"
s -= 1
if s == 0:
m -= 1
s = 59
elif m == 0:
m = 5
self.my_timeBB_time = [m, s]
self.timer_id_BB = self.after(1000, self.my_timeBB_after)
#######################################################
def my_timeRB(self):
self.my_timeRB_time = [4, 59]
#if self.timer_id_RB:
self.after_cancel(self.timer_id_RB)
#self.timer_id_RB = None
self.my_timeRB_after()
def my_timeRB_after(self):
m, s = self.my_timeRB_time
self.label2.configure(text="{0}:{1:02}".format(m, s))
self.label2.update()
#os.system('cls')
print "RB", m, "Minutes", s, "Seconds"
s -= 1
if s == 0:
m -= 1
s = 59
elif m == 0:
m = 5
self.my_timeRB_time = [m, s]
self.timer_id_BB = self.after(1000, self.my_timeRB_after)
#######################################################
def label_clicked(self, event):
self.label1.configure(self.my_timeBB())
self.label1.update()
def label2_clicked(self, event):
self.label2.configure(self.my_timeRB())
self.label2.update()
def label3_clicked(self, even):
self.label3.configure(self.my_timeDrag())
self.label3.update()
##############################################################
League_Jungle_Timer().mainloop()
修复非常简单,但是有点复杂。
你需要使用python的多线程和队列库。
首先要导入:
import threading
import Queue
然后设置线程类:
class ThreadedClient(threading.Thread):
def __init__(self, queue, fcn):
threading.Thread.__init__(self)
self.queue = queue
self.fcn = fcn
def run(self)
time.sleep(1)
self.queue.put(self.fcn())
然后,在League_Jungle_Timer
类中添加两个函数。spawnthread
设置线程,启动线程,然后调用periodiccall
,允许主循环和任何"并发"函数。
def spawnthread(self, fcn):
self.thread = ThreadedClient1(self.queue, fcn)
self.thread.start()
self.periodiccall(thread)
def periodiccall(self):
if self.thread.is_alive():
self.after(100, self.periodiccall)
将这行添加到League_Jungle_Timer
的init方法中以设置队列:
self.queue = Queue.Queue()
使用时,调用lambda: self.spawnthread(self.my_timeBB())
或任何其他您想调用的函数。使用该表达式作为按钮回调或标签配置。