Tkinter解除绑定关键事件问题

2024-05-23 21:07:20 发布

您现在位置:Python中文网/ 问答频道 /正文

在下面的代码中,按空格键两次会连续发出两声蜂鸣音。我想避免这种情况,而是在发出第一声蜂鸣音时禁用钥匙。我原以为解开空格键可能行得通,但行不通。奇怪的是,只有两个嘟嘟声似乎叠加在一起,而不是更多。我猜问题的原因可能是winsound.Beep是非阻塞的,因此重新绑定几乎立即发生

关于如何让它工作,请有任何建议吗

import winsound
from tkinter import *

             
def beep(e):
    frame.unbind("<space>")
    winsound.Beep(440, 1000)
    frame.bind("<space>", beep)


root = Tk()
frame = Frame(root, width=100, height=100)
frame.bind("<space>", beep)
frame.pack()
frame.focus_set()
root.mainloop()

Tags: 代码importbind情况原因spacerootbeep
3条回答

以下是一个解决方案,它将焦点从小部件上移开,因此绑定不会被触发:

import winsound
from tkinter import *

def beep(event):
    dummy.focus_set() #setting focus to dummy
    winsound.Beep(440, 1000) #playing it 
    root.after(1000,frame.focus_set) #setting focus back after playing for 1000 ms

root = Tk()

dummy = Label() #making a dummy widget
dummy.pack()
frame = Frame(root, width=100, height=100)
frame.bind("<space>",beep)
frame.pack()
frame.focus_set()

root.mainloop()

我评论它是为了更好地理解,但这只是一种方法,理解起来也没那么复杂

还请记住,在所有使用winsound的情况下,只要该蜂鸣音开始并结束播放,GUI就会无响应,也就是说,GUI会在1秒内无响应(在您的情况下)

这应该可以解决问题,但是您必须下载带有pip install keyboardkeyboard模块:

import winsound
from tkinter import *
import keyboard
from _thread import start_new_thread

def beep():
    while True:
        if keyboard.is_pressed('space'):
            winsound.Beep(440, 1000)

root = Tk()

frame = Frame(root, width=100, height=100)
start_new_thread(beep, ())
frame.pack()
frame.focus_set()

root.mainloop()

第一个start_new_thread()(语法很重要)使beep()线程化(在后台运行?)并使其成为一个while循环,因此它会连续运行,每当您按空格键时,它将beep,即使您发送垃圾邮件,它也只会运行一个beep。然而,也有不利的一面。它将在脚本未终止时运行,所以如果您将焦点调出,则按空格键时仍会发出嘟嘟声

您可以使用自上次成功keypress以来经过的时间来决定是否应产生蜂鸣音

可能是这样的:我没有访问winsound的权限,所以我使用了os功能来模拟蜂鸣声。您可以对此进行注释,并取消对winsound

# import winsound
import os
import tkinter as tk
import time

             
def beep(e, time_limit=1, timer=[0]):
    t0 = timer[0]
    t1 = time.time()
    delta_t = t1 - t0
    if delta_t < time_limit:
        return
#     winsound.Beep(440, 1000)
    os.system('say "Beep"')    
    timer[0] = t1
    

root = tk.Tk()
frame = tk.Frame(root, width=100, height=100)
frame.bind("<space>", beep)
frame.pack()
frame.focus_set()
root.mainloop()

相关问题 更多 >