使用 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".

时它不会看到