密钥释放事件

时间:2016-04-09 13:14:56

标签: python tkinter

我的要求 我正在开发一个程序,我在其中处理空间和KeyPress-space事件来处理基于时间的事件。

我正在做的是在程序开始时窗口打开以显示时间间隔,比如" 5"其中描绘了5秒。一旦时间过去(5秒),文本" 5"消失了。

之后,用户需要按空格键,当用户按空格键时,将显示相同的数字,直到用户不发布空格键。

我已经给出了2秒间隔来显示下一个间隔(一旦用户释放空间),并且在该间隔中不应出现在先前设置的时间间隔空间中出现的数字事件。

问题陈述: 我面临的问题是我设法在按键时显示数字(文本),但是当我按键释放时,时间间隔不会消失2秒。

这是我的代码:

from tkinter import Label, Tk
import time

times = [3, 4, 5]
loop = 0

class Demo:
    def __init__(self, master):
        global times, loop
        self.parent = master
        self.lbl = Label(master, text=times[loop])
        master.after(times[loop]*1000, self.hideLabelAfterSomeTime)
        master.bind("<space>", self.hideLabel)
        master.bind("<KeyRelease-space>", self.showLabel)
        print('called', loop)
        self.lbl.pack()

    def hideLabel(self, event):
        global loop, times
        self.lbl.config(text=times[loop])
        self.lbl.pack()

    def showLabel(self, event):
        global loop
        self.lbl.pack_forget()
        time.sleep(2)
        loop += 1
        Demo(self.parent)

    def hideLabelAfterSomeTime(self):
        self.lbl.config(text= '')

master = Tk()
app = Demo(master)
master.geometry("400x300+400+200")
master.mainloop()

2 个答案:

答案 0 :(得分:1)

你去..如果你有任何进一步的询问,请告诉我 -

from tkinter import Label, Tk
import time

times = [3, 4, 5]
loop = 0

class Demo:
    def __init__(self, master):
        global times, loop
        self.parent = master
        self.lbl = Label(master, text=times[loop])
        master.after(times[loop]*1000, self.hideLabelAfterSomeTime)
        master.bind("<space>", self.hideLabel)

    master.bind("<KeyRelease-space>", self.showLabel)
    print('called', loop)
    self.lbl.pack()

def hideLabel(self, event):
    global loop, times
    self.lbl.config(text=times[loop])
    self.lbl.pack()

def showLabel(self, event):

    global loop
    self.lbl.pack_forget() 
    self.parent.update()
    time.sleep(2)
    loop += 1
    Demo(self.parent)

def hideLabelAfterSomeTime(self):
    self.lbl.config(text= '')

master = Tk()
app = Demo(master)
master.geometry("400x300+400+200")
master.mainloop()

答案 1 :(得分:0)

您似乎在Python与Tk主循环交互的方式中找到了“缝隙”。至少在我的系统(Python 2.7,Fedora 22,x86_64)上, showLabel()中的任何操作都不会对屏幕产生任何影响,直到该函数(包括 time.sleep(2)) 完成。

如果您按照以下方式修改代码以进行故障排除,我想您可以看到我的意思。

def hideLabel(self, event):
    global loop, times
#       self.lbl.config(text=times[loop])
    self.lbl.config(bg = "red")
    self.lbl.pack()

def showLabel(self, event):
    global loop
#       self.lbl.pack_forget()
    self.lbl.config(fg = "blue")
    time.sleep(2)
    loop += 1
    Demo(self.parent)

def hideLabelAfterSomeTime(self):
#       self.lbl.config(text= '')
    self.lbl.config(bg = "green")

第二个标签现在显示在第一个标签下面。正如我们所料,第一个标签获得蓝色前景,而不是按键。它显然只在函数返回时才得到它,在 time.sleep()之后。

我并不假装完全理解这一点 - 对Python和Tk有深刻理解的人可能会解释。此特定程序的一种解决方法是添加 update_idletasks()。这(警告:前面的草率术语)强制Tk主循环立即处理未决事件。

def showLabel(self, event):
    global loop
#   self.lbl.pack_forget()
    self.lbl.config(fg = "blue")
    master.update_idletasks()
    time.sleep(2)
    loop += 1
    Demo(self.parent)

在我的系统上,使第一个标签在time.sleep()之前变为蓝色。我没有超越那个实验。 p.showLabel()隐藏标签,hideLabel()显示它?

编辑:以下轻微的原始发布代码可以在我的系统上运行,几乎和我期望的一样。我不是100%确定它打算做什么。但是当我点击空格键时,当前标签确实消失了,下一个标签在2秒后出现,只是在此之后的一个可变时间被消隐。

我遇到的唯一难题是,当我试图按住空格键超过2秒时,我的系统基本上变得疯狂了。事实证明,关键的自动重复是在我的系统上踢,导致我几十次击键并导致数十个下标超出范围的错误。我放弃了这一点,所以我仍然不知道程序如果给出一个空格下降后3秒后单个空间上升的行为。

from Tkinter import Label, Tk
import time

times = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]
loop = 0

class Demo:
    def __init__(self, master):
        global times, loop
        self.parent = master
        self.lbl = Label(master, text=times[loop])
        master.after(times[loop]*1000, self.hideLabelAfterSomeTime)
        master.bind("<space>", self.hideLabel)
        master.bind("<KeyRelease-space>", self.showLabel)
        master.bind("<h>", self.showLabel)
        print('called', loop)
        self.lbl.pack()
        for child in master.children: print child

    def hideLabel(self, event):
        global loop, times
        self.lbl.config(text=times[loop])
        self.lbl.pack()

    def showLabel(self, event):
        global loop
        self.lbl.pack_forget()
        master.update_idletasks()
        time.sleep(2)
        loop += 1
        Demo(self.parent)

    def hideLabelAfterSomeTime(self):
        self.lbl.config(text= '')
        self.lbl.config(bg = "green")

master = Tk()
app = Demo(master)
master.geometry("400x300+400+200")
master.mainloop()

如果pack_forget对你的系统没有影响,即使使用update_idletasks(),我也不得不猜测Tk主循环比广为人知的更依赖于平台。