0

Initially running the code, blinking will start row wise. What my software should do is that if the user gives the input "1" in the last row textarea,the blinking should start column wise.

Again if the user give the input "1" then the letter should be selected and should be displayed on the top textarea and entire process should start again I am not able to control the while loop when the user gives the input in the last row textarea.

I am beginner in python tkinter and I am not able to do what I want exactly.

Thanking You in advance

# 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()
1
  • 1
    In addition to the looping problems here, E2.get() will always return a string, so comparing E2.get() == 1 will never equate. Commented May 4, 2016 at 15:33

3 Answers 3

1

The problem is that your while loop runs in like a blink of an eye, and you cant input anything meanwhile. Because of the after calls the blinking persist, but that does not mean you are still in your wile loop. The program exited that loop long when you input something into the box.

What i would do is to bind the entry box to a key (like Return) and when the key is pressed check the content of the entry box, and if it is 1 then stop the blinking.

Also you can just bind this whole stuff to the 1 key, and avoid the whole Entry widget stuff

Sign up to request clarification or add additional context in comments.

4 Comments

I had also tried in the way in which you are telling by making a button which when presses check the value in the entry box.But It is still not working if I compare the new value in entry box with any digit
E2 = Entry(top, bd =5,width=40) E2.grid(columnspan=10) content = E2.get() content=0; def on_button(): global content content=E2.get() button = Tkinter.Button(top, text="Get", command=on_button) button.grid()
And if I am breaking the loop when content=="1" ,its doesnt break.
The loop wont break, as the loop will finish much sooner then you can input anything. Just recolor the boxes, or deactivate the coloring on bind event
1

Let's think about what you are trying to accomplish: you are trying to cycle through a list of objects, "blinking" one at a time. You want to first do this for objects one row at a time, and later for objects one column at a time.

I am assuming the only thing different between these two behaviors is which items it is iterating over. So, if you create a general purpose function for "blinking" sequentially through a list of objects, you can simply switch which objects are being "blinked".

How would this work? Let's start by creating a list of things to "blink":

blink_objects = [row1, row2, row3, row4]

The idea is that we want to "blink" these, one at a time. To change what is blinking (to switch from rows to columns, as in your question), you simply need to redefine blink_objects.

How would we go about blinking them? The normal way to do this sort of animation is to create a function that draws one frame of the animation, and then schedules itself to run again after a short period of time. In your case that period of time is one second.

Let's call this function blink. We want it to take a couple of optional args, which will be of use later. The first is a variable that contains the object that is currently in a "blink" state. We need this so that we can change it back. The second is a flag that we can use to stop the animation in the future.

Here's what the function looks like. The current_object parameter is passed internally by blink and shouldn't be set when calling blink from somewhere else.

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)

You only need to call this function once. It will take care of calling itself again every second until the end of time. To get this to blink like your original program, we simply need to replace your whole while loop with these two lines of code:

blink_objects = [row1, row2, row3, row4]
blink()

If at any time you want to stop the animation, you can call blink(stop=True). You might want to do that when the user quits your program, for example.

Next, we need to set it up so that typing "i" changes what is blinking. We can do that by setting a specific binding that will fire immediately when the user presses the key:

E2.bind("<i>", change_blink_objects)

What that says is "if the user presses 'i', call change_blink_objects". Now we just need to define change_blink_objects.

Since this function is called from a binding, it will be passed an object that represents the event (what key was pressed, what object got the keypress, etc). At the moment we don't need that information, but we have to accept it.

Within the function, I'm guessing you'll it to intelligently pick the objects to blink, but I don't know what that logic is, so I'll just have it blink the "alarm" row.

def change_blink_objects(event):
    global blink_objects
    blink_objects = [H, I, J, K,. L)

That's all you have to do: create a generic function for blinking a list of objects, and a binding that calls a function that changes the list of objects.

Make sure when you're testing this that you first click in the entry widget or it won't see when you type "i".

Comments

0

While loops and GUIs do not mix very well. Youe while loop creates 240 delayed callbacks that you cannot cancel. Instead, you should have one delayed callback that conditionally creates another. Here is an untested replacement for your loop. It incorporates Gabor's answer and should get you started,

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.