Python - While循环更改变量

时间:2016-01-21 10:49:56

标签: python tkinter

我目前创建的程序会不断检查按键,如果它是W或S,它会改变速度。但是我有Tk没有回应的问题?任何人都欢呼喝彩。我的代码是:

 import tkinter as tk #Importing the GUI Library
import time #Importing Time#
def onKeyPress(event): #Defining my function of keypress, and using GUI Library to get the keypress.
        time.sleep(1) #Telling it to wait one second otherwise it will crash.
        text.insert('end', 'You pressed %s\n' % (event.char, )) #Telling the user if he pressed the key or not.
        speed = 50 #Setting the speed to 50 default
        while speed > 0:
            if event.char == 'w': #if key pressed = w:
                speed = speed + 1 #Change speed by 1
                time.sleep(1)
            if event.char == 's':
                speed = speed - 1
                time.sleep(1)
                print(speed)


root = tk.Tk()
root.geometry('300x200')
text = tk.Text(root, background='black', foreground='white', font=('Comic Sans MS', 12))
text.pack()
root.bind('<KeyPress>', onKeyPress)
root.mainloop()

4 个答案:

答案 0 :(得分:2)

你的主要问题是,当你按下's'以外的字母时,你进入了一个无限循环。按's'时,退出循环将需要50秒才会在下一次按键时再次开始。此外,您的速度变量仅在按键功能内部,因此您无论如何都无法访问它,每次按下键时您也将其重置为50

关于tkinter,您需要了解的几个关键事项是:from collections import defaultdict a = defaultdict(lambda: [set(), set()]) a[100][2].add(2) print(a.items()) 应该大量避免,并尝试让while循环在后台运行。

现在有几个选项可以做到这一点。您可以将函数绑定到每个单独的键。

time.sleep

或者像以前一样使用if语句来检查输入的字母。每个字母使用import tkinter as tk def onKeyPress(event, value): global speed # alter the global speed variable inside a function # Keep in mind this insert will only occur for the selected keys text.insert('end', 'You pressed %s\n' % (event.char, )) speed += value # update speed variable with value print(speed) # print current speed speed = 50 root = tk.Tk() root.geometry('300x200') text = tk.Text(root, background='black', foreground='white', font=('Comic Sans MS', 12)) text.pack() # Individual key bindings root.bind('<KeyPress-w>', lambda e: onKeyPress(e, 1)) # value is 1 for 'w' root.bind('<KeyPress-s>', lambda e: onKeyPress(e, -1)) # value is -1 for 's' root.mainloop() 而不是if elif是因为虽然它具有相同的效果,但if条件为True时终止if块,否则它将遍历所有if语句。

if

旁注:

目前,当我按下一封信时,由于初始按键,它会插入import tkinter as tk def onKeyPress(event): global speed # alter the global speed variable inside a function text.insert('end', 'You pressed %s\n' % (event.char, )) if event.char == 'w': speed += 1 elif event.char == 's': speed -= 1 print(speed) # print current speed speed = 50 root = tk.Tk() root.geometry('300x200') text = tk.Text(root, background='black', foreground='white', font=('Comic Sans MS', 12)) text.pack() root.bind('<KeyPress>', onKeyPress) root.mainloop() 。如果你在插入行之前添加它,那么它将删除给出"sYou pressed s"的类型字符。

"You pressed s"

答案 1 :(得分:1)

Tk没有响应,因为事件处理程序中的while循环永远不会完成。 看来你甚至不需要它在那个地方,所以而不是

def onKeyPress(event):
    while True:
        time.sleep(1)
        text.insert('end', 'You pressed %s\n' % (event.char, ))
    ....

简单地

def onKeyPress(event):
    text.insert('end', 'You pressed %s\n' % (event.char, ))
    ...

应该做的。

主循环不在单个事件处理程序中,而是在外部并且已经由最后一行启动。

答案 2 :(得分:0)

你永远不能在主线程或主进程中同时执行gui和循环等两件事。你正在使用while循环。所以当程序进入while循环时它会连续运行而不给gui提供任何资源。登记/> 所以利用线程模块和队列来完成这项工作。

答案 3 :(得分:-1)

我没有看到你想要的内容和代码中的内容之间的关系:

def onKeyPress(event):
    time.sleep(1) #Telling it to wait one second otherwise it will crash.
    text.insert('end', 'You pressed %s\n' % (event.char, ))
    speed = 50      # This is set on each keypress?
    while speed > 0:         # why?
        if event.char == 'w':
            speed = speed + 1
            time.sleep(1)
        if event.char == 's':
            speed = speed - 1
            time.sleep(1)
            print(speed)     # inside the second if? Why?

首先,每按一次键(任意键),速度都设为50。

其次,你为什么在'keypress'功能中有一个循环?
每次按(任意)键时都会调用此函数,因此如果按'w'然后按's'或甚至't',每个键都会有一个函数调用。

让我们说你按'w',然后:
- 调用该函数:设置速度= 50
- 你输入一个while循环,(speed&gt; 0)
- 检查按下的键 - 因为它是'w',速度= 51
- 因为速度> 0,重做循环 -----&GT;这将“永远”不会结束,因为速度永远不会<0并且不会打印速度值。

让我们说你按's',然后:
- 调用该函数:设置速度= 50
- 你输入一个while循环,(speed&gt; 0)
- 检查按下的键 - 因为它是's',速度= 49
- 打印速度值
- 因为速度> 0,重做循环。 -----&GT;这最终会结束。

假设您按下其他键,然后:
- 调用该函数:设置速度= 50
- 你输入一个while循环,(speed&gt; 0)
- 检查按下的键 - 因为它是另一个键,速度= 50,没有改变 - 因为速度> 0,重做循环....永远... ----&GT;在这种情况下,你将拥有一个永无止境的循环而不打印任何东西。

你想要什么(我认为)? 这对我有用。

speed = 50   #Leave it out of the function.
def onKeyPress(event):
    #time.sleep(1) # You shouldn't have a sleep() inside a function called by tkinter.
    text.insert('end', 'You pressed %s\n' % (event.char, ))
    global speed     #So you can alter its value
    #No loop inside function
    if event.char == 'w':
        speed = speed + 1
    if event.char == 's':
        speed = speed - 1
    print(speed)     # Outside of function, so you can see the present value.