按住按钮和窗口更新问题

时间:2017-06-22 04:06:25

标签: python python-2.7 tkinter

当我一直按住Ctrl+Up时,我需要标签以1000毫秒的间隔更新。 (如果我按住Ctrl+Up 5秒钟,命令应运行5次。)

after方法似乎不起作用。它也很奇怪,好像它记录了我按下键的次数,并且即使在Ctrl+Up未被按下之后也会保持循环。

from Tkinter import * 

root = Tk()

def start(event):
    global x
    x = x+1
    x_var.set(x)
    root.after(1000, lambda: start(event))

x=1

x_var=IntVar()
x_var.set(x)

r = Label(root, textvariable=x_var)
r.pack()

root.bind('<Control-Up>', start)
root.mainloop()

2 个答案:

答案 0 :(得分:1)

  

after方法似乎不起作用。

不,它正在你的程序要求它。

  

它也很奇怪,好像它记录了我按下键的次数   并且在按下Ctrl + Up之后保持循环。

这并不奇怪。瞥一眼给定的documentation,你会看到:

  

每次调用此方法时,只会调用一次回调。保持   调用回调,你需要在中重新注册回调   的本身

粗体文字是您在start()函数中的确切行为。因此,当前代码的逻辑行为是,一旦按 Ctrl + Up ,该回调将等待1000毫秒执行,之后它将继续永远运行(好吧,直到你结束mainloop()事件)

因此,为了使您的程序在每次按下您指定的键后仅增加标签的内容一次,您需要避免使用上面以粗体文字书写的设计。然后,解决方案可以包括创建一个特定的增量函数,如下所示:

def increment_x():
   global x, x_var
   x += 1
   x_var.set(x)

然后在start()函数中使用此函数作为回调:

def start(event):    
    root.after(1000, increment_x)

所以你的代码变成了:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from Tkinter import * 

root = Tk()    

def start(event):    
    root.after(1000, increment_x)

def increment_x():
   global x, x_var
   x += 1
   x_var.set(x)


x=1

x_var=IntVar()
x_var.set(x)

r = Label(root, textvariable=x_var)
r.pack()

root.bind('<Control-Up>', start)
root.mainloop()

P.S。请关注PEP8

答案 1 :(得分:1)

这是一种在持有 Control + Up 的情况下每1000毫秒运行一个命令的方法:

  • 存储并更新 Control current pressed statuses Up

  • 有一个.after()循环,每1000毫秒调用一次,如果当前按下 Control Up ,则运行所需的命令

<强>代码

import Tkinter as tk

root = tk.Tk()

x = 1
x_var = tk.IntVar()
x_var.set(x)

r = tk.Label(root, textvariable=x_var)
r.pack()

isPressed = {"Control_L": False, "Up": False}

def update_key_status(key, value):
    global isPressed
    isPressed[key] = value

# Make the Press/Release events of both keys update the "isPressed" dictionary
for key in ["Up", "Control_L"]:
    root.bind('<KeyPress-{}>'.format(key), 
              lambda evt, key=key: update_key_status(key, True))
    root.bind('<KeyRelease-{}>'.format(key), 
              lambda evt, key=key: update_key_status(key, False))

def increment_x():
    global x, x_var
    x += 1
    x_var.set(x)

def start():
    if (isPressed["Control_L"] and isPressed["Up"]):
        increment_x()
    root.after(1000, start)

start()
root.mainloop()