使用 python tkinter 的问题
Problems in using python tkinter
最初 运行 代码,闪烁将按行开始。
我的软件应该做的是,如果用户在最后一行文本区域中输入“1”,则闪烁应该按列开始。
同样,如果用户输入“1”,则应选择该字母并应显示在顶部文本区域中,整个过程应重新开始
当用户在最后一行 textarea 中输入时,我无法控制 while 循环。
我是 python tkinter 的初学者,我无法完全按照自己的意愿去做。
提前致谢
# your code goes here
import Tkinter
from Tkinter import *
import tkMessageBox
top = Tkinter.Tk()
content=0
def helloCallBack1():
tkMessageBox.showinfo( "Hello Python", "Hello World")
L1 = Label(top, text="Your Text Appears Here")
L1.grid(columnspan=10)
E1 = Entry(top, bd =5,width=40)
E1.grid(columnspan=10)
a1 = Tkinter.Button(top, text ="WATER",width="10", command = helloCallBack1)
a1.grid(row=4,column=0)
B = Tkinter.Button(top, text ="B", command = helloCallBack1)
B.grid(row=4,column=1)
C = Tkinter.Button(top, text ="C",command = helloCallBack1)
C.grid(row=4,column=2)
D = Tkinter.Button(top, text ="D", command = helloCallBack1)
D.grid(row=4,column=3)
E = Tkinter.Button(top, text ="E", command = helloCallBack1)
E.grid(row=4,column=4)
F = Tkinter.Button(top, text ="F", command = helloCallBack1)
F.grid(row=4,column=5)
row1 = Tkinter.Button(top, text =" ", command = helloCallBack1)
row1.grid(row=4,column=6)
a1 = Tkinter.Button(top, text ="ALARM",width="10",bg="red", command = helloCallBack1)
a1.grid(row=5,column=0)
H = Tkinter.Button(top, text ="H", command = helloCallBack1)
H.grid(row=5,column=1)
I = Tkinter.Button(top, text ="I", command = helloCallBack1)
I.grid(row=5,column=2)
J = Tkinter.Button(top, text ="J", command = helloCallBack1)
J.grid(row=5,column=3)
K = Tkinter.Button(top, text ="K", command = helloCallBack1)
K.grid(row=5,column=4)
L = Tkinter.Button(top, text ="L", command = helloCallBack1)
L.grid(row=5,column=5)
row2 = Tkinter.Button(top, text =" ", command = helloCallBack1)
row2.grid(row=5,column=6)
a1 = Tkinter.Button(top, text ="FOOD",width="10", command = helloCallBack1)
a1.grid(row=6,column=0)
N = Tkinter.Button(top, text ="N", command = helloCallBack1)
N.grid(row=6,column=1)
O = Tkinter.Button(top, text ="O",command = helloCallBack1)
O.grid(row=6,column=2)
P = Tkinter.Button(top, text ="P", command = helloCallBack1)
P.grid(row=6,column=3)
Q = Tkinter.Button(top, text ="Q",command = helloCallBack1)
Q.grid(row=6,column=4)
R = Tkinter.Button(top, text ="R", command = helloCallBack1)
R.grid(row=6,column=5)
row3 = Tkinter.Button(top, text =" ", command = helloCallBack1)
row3.grid(row=6,column=6)
a4 = Tkinter.Button(top, text ="BACKSPACE",width="10", command = helloCallBack1)
a4.grid(row=7,column=0)
S = Tkinter.Button(top, text ="S", command = helloCallBack1)
S.grid(row=7,column=1)
T = Tkinter.Button(top, text ="T", command = helloCallBack1)
T.grid(row=7,column=2)
U = Tkinter.Button(top, text ="U", command = helloCallBack1)
U.grid(row=7,column=3)
V = Tkinter.Button(top, text ="V", command = helloCallBack1)
V.grid(row=7,column=4)
W = Tkinter.Button(top, text ="W", command = helloCallBack1)
W.grid(row=7,column=5)
row4 = Tkinter.Button(top, text =" ", command = helloCallBack1)
row4.grid(row=7,column=6)
L2 = Label(top, text="Press 1 when you want to select")
L2.grid(columnspan=10)
E2 = Entry(top, bd =5,width=40)
E2.grid(columnspan=10)
content = E2.get()
content=0;
i=0;j=0;
while(i<30):
row1.after(4000*j+1000*i, lambda: row1.config(fg="red",bg="black"))
row1.after(4000*j+1000*(i+1), lambda: row1.config(fg="grey",bg=top["bg"]))
row2.after(4000*j+1000*(i+1), lambda: row2.config(fg="red",bg="black"))
row2.after(4000*j+1000*(i+2), lambda: row2.config(fg="grey",bg=top["bg"]))
row3.after(4000*j+1000*(i+2), lambda: row3.config(fg="red",bg="black"))
row3.after(4000*j+1000*(i+3), lambda: row3.config(fg="grey",bg=top["bg"]))
row4.after(4000*j+1000*(i+3), lambda: row4.config(fg="red",bg="black"))
row4.after(4000*j+1000*(i+4), lambda: row4.config(fg="grey",bg=top["bg"]))
content=E2.get()
if content==1:#this is not working
break
i=i+1
j=j+1
top.mainloop()
问题是你的while循环一眨眼就跑完了,同时你不能输入任何东西。由于 after
调用闪烁持续存在,但这并不意味着您仍处于 wile 循环中。当您在框中输入内容时,程序会退出该循环。
我要做的是将输入框绑定到一个键(如Return),当按下该键时检查输入框的内容,如果是 1 则停止闪烁。
您也可以将所有内容绑定到 1
键,避免使用整个 Entry 小部件内容
虽然循环和 GUI 不能很好地混合。您的 while 循环会创建 240 个无法取消的延迟回调。相反,您应该有一个有条件地创建另一个的延迟回调。这是您的循环的未经测试的替代品。它结合了 Gabor 的回答,应该可以帮助您入门,
go = True
def stop():
go = False
root.bind('<key-1>', stop)
def blink(i, j):
if i = 0:
row1.config(fg="red",bg="black"))
if j > 0:
row4.config(fg="grey",bg=top["bg"]))
elif i = 1:
row1.config(fg="grey",bg=top["bg"]))
row2.config(fg="red",bg="black"))
elif i = 2:
row2.config(fg="grey",bg=top["bg"]))
row3.config(fg="red",bg="black"))
elif i = 3:
row3.config(fg="grey",bg=top["bg"]))
row4.config(fg="red",bg="black"))
if go and j < 30:
top.after(1000, blink, (i+1) % 4, j+1)
top.after(1000, blink, 0, 0)
让我们考虑一下您要完成的任务:您正在尝试循环访问一个对象列表,"blinking" 一次一个。您希望首先对对象一次一行执行此操作,然后一次对对象一列执行此操作。
我假设这两种行为之间唯一不同的是它正在迭代哪些项目。因此,如果您通过对象列表按顺序为 "blinking" 创建一个通用函数,您可以简单地切换哪些对象是 "blinked".
这将如何运作?让我们首先创建一个列表,内容为 "blink":
blink_objects = [row1, row2, row3, row4]
我们的想法是 "blink" 这些,一次一个。要更改闪烁的内容(如您的问题所示,从行切换到列),您只需重新定义 blink_objects
.
我们如何让它们眨眼?制作这种动画的正常方法是创建一个函数来绘制动画的一帧,然后在短时间后再次安排自己到 运行。在你的情况下,这段时间是一秒钟。
我们称这个函数为blink
。我们希望它带有几个可选的参数,稍后会有用。第一个是包含当前处于 "blink" 状态的对象的变量。我们需要这个,以便我们可以将它改回来。第二个是我们以后可以用来停止动画的标志。
函数如下所示。 current_object
参数由 blink
内部传递,在从其他地方调用 blink
时不应设置。
def blink(current_object = None, stop=False):
global blink_objects
# "unblink" the current object
if current_object:
current_object.configure(fg="black", bg=top["bg"])
current_object = None
if not stop:
# blink the first item in the list of objects,
# then move the object to the end of the list
current_object = blink_objects.pop(0)
blink_objects.append(current_object)
current_object.configure(bg="black", fg="red")
# schedule the blink again after a second
current_object.after(1000, blink, current_object)
您只需调用此函数一次。它将负责每秒再次调用自己,直到时间结束。为了让它像您的原始程序一样闪烁,我们只需要用以下两行代码替换您的整个 while
循环:
blink_objects = [row1, row2, row3, row4]
blink()
如果你想在任何时候停止动画,你可以调用blink(stop=True)
。例如,当用户退出您的程序时,您可能希望这样做。
接下来,我们需要对其进行设置,以便键入 "i" 更改闪烁的内容。我们可以通过设置一个特定的绑定来做到这一点,该绑定将在用户按下该键时立即触发:
E2.bind("<i>", change_blink_objects)
说的是"if the user presses 'i', call change_blink_objects"。现在我们只需要定义change_blink_objects
。
由于此函数是从绑定中调用的,因此它将传递一个表示事件的对象(按下了什么键,哪个对象得到了按键等)。目前我们不需要这些信息,但我们必须接受它。
在函数中,我猜你会智能地选择要闪烁的对象,但我不知道那个逻辑是什么,所以我让它闪烁 "alarm"排。
def change_blink_objects(event):
global blink_objects
blink_objects = [H, I, J, K,. L)
这就是您要做的所有事情:创建一个通用函数来闪烁对象列表,以及一个调用函数来更改对象列表的绑定。
确保在测试时首先单击条目小部件,否则在您键入 "i".
时它不会看到
最初 运行 代码,闪烁将按行开始。 我的软件应该做的是,如果用户在最后一行文本区域中输入“1”,则闪烁应该按列开始。
同样,如果用户输入“1”,则应选择该字母并应显示在顶部文本区域中,整个过程应重新开始 当用户在最后一行 textarea 中输入时,我无法控制 while 循环。
我是 python tkinter 的初学者,我无法完全按照自己的意愿去做。
提前致谢
# your code goes here
import Tkinter
from Tkinter import *
import tkMessageBox
top = Tkinter.Tk()
content=0
def helloCallBack1():
tkMessageBox.showinfo( "Hello Python", "Hello World")
L1 = Label(top, text="Your Text Appears Here")
L1.grid(columnspan=10)
E1 = Entry(top, bd =5,width=40)
E1.grid(columnspan=10)
a1 = Tkinter.Button(top, text ="WATER",width="10", command = helloCallBack1)
a1.grid(row=4,column=0)
B = Tkinter.Button(top, text ="B", command = helloCallBack1)
B.grid(row=4,column=1)
C = Tkinter.Button(top, text ="C",command = helloCallBack1)
C.grid(row=4,column=2)
D = Tkinter.Button(top, text ="D", command = helloCallBack1)
D.grid(row=4,column=3)
E = Tkinter.Button(top, text ="E", command = helloCallBack1)
E.grid(row=4,column=4)
F = Tkinter.Button(top, text ="F", command = helloCallBack1)
F.grid(row=4,column=5)
row1 = Tkinter.Button(top, text =" ", command = helloCallBack1)
row1.grid(row=4,column=6)
a1 = Tkinter.Button(top, text ="ALARM",width="10",bg="red", command = helloCallBack1)
a1.grid(row=5,column=0)
H = Tkinter.Button(top, text ="H", command = helloCallBack1)
H.grid(row=5,column=1)
I = Tkinter.Button(top, text ="I", command = helloCallBack1)
I.grid(row=5,column=2)
J = Tkinter.Button(top, text ="J", command = helloCallBack1)
J.grid(row=5,column=3)
K = Tkinter.Button(top, text ="K", command = helloCallBack1)
K.grid(row=5,column=4)
L = Tkinter.Button(top, text ="L", command = helloCallBack1)
L.grid(row=5,column=5)
row2 = Tkinter.Button(top, text =" ", command = helloCallBack1)
row2.grid(row=5,column=6)
a1 = Tkinter.Button(top, text ="FOOD",width="10", command = helloCallBack1)
a1.grid(row=6,column=0)
N = Tkinter.Button(top, text ="N", command = helloCallBack1)
N.grid(row=6,column=1)
O = Tkinter.Button(top, text ="O",command = helloCallBack1)
O.grid(row=6,column=2)
P = Tkinter.Button(top, text ="P", command = helloCallBack1)
P.grid(row=6,column=3)
Q = Tkinter.Button(top, text ="Q",command = helloCallBack1)
Q.grid(row=6,column=4)
R = Tkinter.Button(top, text ="R", command = helloCallBack1)
R.grid(row=6,column=5)
row3 = Tkinter.Button(top, text =" ", command = helloCallBack1)
row3.grid(row=6,column=6)
a4 = Tkinter.Button(top, text ="BACKSPACE",width="10", command = helloCallBack1)
a4.grid(row=7,column=0)
S = Tkinter.Button(top, text ="S", command = helloCallBack1)
S.grid(row=7,column=1)
T = Tkinter.Button(top, text ="T", command = helloCallBack1)
T.grid(row=7,column=2)
U = Tkinter.Button(top, text ="U", command = helloCallBack1)
U.grid(row=7,column=3)
V = Tkinter.Button(top, text ="V", command = helloCallBack1)
V.grid(row=7,column=4)
W = Tkinter.Button(top, text ="W", command = helloCallBack1)
W.grid(row=7,column=5)
row4 = Tkinter.Button(top, text =" ", command = helloCallBack1)
row4.grid(row=7,column=6)
L2 = Label(top, text="Press 1 when you want to select")
L2.grid(columnspan=10)
E2 = Entry(top, bd =5,width=40)
E2.grid(columnspan=10)
content = E2.get()
content=0;
i=0;j=0;
while(i<30):
row1.after(4000*j+1000*i, lambda: row1.config(fg="red",bg="black"))
row1.after(4000*j+1000*(i+1), lambda: row1.config(fg="grey",bg=top["bg"]))
row2.after(4000*j+1000*(i+1), lambda: row2.config(fg="red",bg="black"))
row2.after(4000*j+1000*(i+2), lambda: row2.config(fg="grey",bg=top["bg"]))
row3.after(4000*j+1000*(i+2), lambda: row3.config(fg="red",bg="black"))
row3.after(4000*j+1000*(i+3), lambda: row3.config(fg="grey",bg=top["bg"]))
row4.after(4000*j+1000*(i+3), lambda: row4.config(fg="red",bg="black"))
row4.after(4000*j+1000*(i+4), lambda: row4.config(fg="grey",bg=top["bg"]))
content=E2.get()
if content==1:#this is not working
break
i=i+1
j=j+1
top.mainloop()
问题是你的while循环一眨眼就跑完了,同时你不能输入任何东西。由于 after
调用闪烁持续存在,但这并不意味着您仍处于 wile 循环中。当您在框中输入内容时,程序会退出该循环。
我要做的是将输入框绑定到一个键(如Return),当按下该键时检查输入框的内容,如果是 1 则停止闪烁。
您也可以将所有内容绑定到 1
键,避免使用整个 Entry 小部件内容
虽然循环和 GUI 不能很好地混合。您的 while 循环会创建 240 个无法取消的延迟回调。相反,您应该有一个有条件地创建另一个的延迟回调。这是您的循环的未经测试的替代品。它结合了 Gabor 的回答,应该可以帮助您入门,
go = True
def stop():
go = False
root.bind('<key-1>', stop)
def blink(i, j):
if i = 0:
row1.config(fg="red",bg="black"))
if j > 0:
row4.config(fg="grey",bg=top["bg"]))
elif i = 1:
row1.config(fg="grey",bg=top["bg"]))
row2.config(fg="red",bg="black"))
elif i = 2:
row2.config(fg="grey",bg=top["bg"]))
row3.config(fg="red",bg="black"))
elif i = 3:
row3.config(fg="grey",bg=top["bg"]))
row4.config(fg="red",bg="black"))
if go and j < 30:
top.after(1000, blink, (i+1) % 4, j+1)
top.after(1000, blink, 0, 0)
让我们考虑一下您要完成的任务:您正在尝试循环访问一个对象列表,"blinking" 一次一个。您希望首先对对象一次一行执行此操作,然后一次对对象一列执行此操作。
我假设这两种行为之间唯一不同的是它正在迭代哪些项目。因此,如果您通过对象列表按顺序为 "blinking" 创建一个通用函数,您可以简单地切换哪些对象是 "blinked".
这将如何运作?让我们首先创建一个列表,内容为 "blink":
blink_objects = [row1, row2, row3, row4]
我们的想法是 "blink" 这些,一次一个。要更改闪烁的内容(如您的问题所示,从行切换到列),您只需重新定义 blink_objects
.
我们如何让它们眨眼?制作这种动画的正常方法是创建一个函数来绘制动画的一帧,然后在短时间后再次安排自己到 运行。在你的情况下,这段时间是一秒钟。
我们称这个函数为blink
。我们希望它带有几个可选的参数,稍后会有用。第一个是包含当前处于 "blink" 状态的对象的变量。我们需要这个,以便我们可以将它改回来。第二个是我们以后可以用来停止动画的标志。
函数如下所示。 current_object
参数由 blink
内部传递,在从其他地方调用 blink
时不应设置。
def blink(current_object = None, stop=False):
global blink_objects
# "unblink" the current object
if current_object:
current_object.configure(fg="black", bg=top["bg"])
current_object = None
if not stop:
# blink the first item in the list of objects,
# then move the object to the end of the list
current_object = blink_objects.pop(0)
blink_objects.append(current_object)
current_object.configure(bg="black", fg="red")
# schedule the blink again after a second
current_object.after(1000, blink, current_object)
您只需调用此函数一次。它将负责每秒再次调用自己,直到时间结束。为了让它像您的原始程序一样闪烁,我们只需要用以下两行代码替换您的整个 while
循环:
blink_objects = [row1, row2, row3, row4]
blink()
如果你想在任何时候停止动画,你可以调用blink(stop=True)
。例如,当用户退出您的程序时,您可能希望这样做。
接下来,我们需要对其进行设置,以便键入 "i" 更改闪烁的内容。我们可以通过设置一个特定的绑定来做到这一点,该绑定将在用户按下该键时立即触发:
E2.bind("<i>", change_blink_objects)
说的是"if the user presses 'i', call change_blink_objects"。现在我们只需要定义change_blink_objects
。
由于此函数是从绑定中调用的,因此它将传递一个表示事件的对象(按下了什么键,哪个对象得到了按键等)。目前我们不需要这些信息,但我们必须接受它。
在函数中,我猜你会智能地选择要闪烁的对象,但我不知道那个逻辑是什么,所以我让它闪烁 "alarm"排。
def change_blink_objects(event):
global blink_objects
blink_objects = [H, I, J, K,. L)
这就是您要做的所有事情:创建一个通用函数来闪烁对象列表,以及一个调用函数来更改对象列表的绑定。
确保在测试时首先单击条目小部件,否则在您键入 "i".
时它不会看到