【问题标题】:Executing an keypress event while playing a sound in python(tkinter)在python(tkinter)中播放声音时执行按键事件
【发布时间】:2012-11-16 20:25:29
【问题描述】:

我是编程新手,对 python 知之甚少。我正在尝试制作一个程序来测试生物学实验的听觉和视觉反应时间。 对于听觉部分,我在声音开始播放时启动计时器,然后受试者必须在听到它时立即按下一个键。我的问题是,虽然声音仍在播放,但我无法执行任何其他操作,因此无法记录按下键的时间。 这是我正在尝试做的简化版本:

from Tkinter import *
import time
import winsound

def chooseTest(event):
    global start
    if event.keysym == 'BackSpace':
       root.after(2000,playSound)
    elif event.keysym == 'Return':
       new_time = time.clock()
       elapsed = new_time - start
       print elapsed
    else:
       pass

def playSound():
    global start
    start = time.clock()
    winsound.PlaySound('SystemAsterisk', winsound.SND_ALIAS)

root=Tk()
root.overrideredirect(True)
root.geometry("{0}x{1}+0+0".format(root.winfo_screenwidth(),root.winfo_screenheight()))           
root.bind('<Key>',chooseTest)
root.mainloop()

我在 elif event.keysym == 'Return': 下放置的任何内容都只会在声音结束后执行。 有没有办法(希望不是很复杂)来克服这个问题?
我能想出的唯一解决方案是发出很短的声音(毫秒?)并循环播放直到按键被按下。

谢谢。

【问题讨论】:

    标签: python audio tkinter


    【解决方案1】:

    您需要在单独的thread 上启动声音。

    类似:

    import threading
    
    #...
    
    def playSound():
        global start
        start = time.clock()
    
        def func(): 
            winsound.PlaySound('SystemAsterisk', winsound.SND_ALIAS)
    
        threading.Thread(target=func).start()
    

    顺便说一句,像这样悬挂全局值并不是最好的解决方案。您应该阅读类,因为它们是在各种函数调用之间共享状态的一种非常好的方式。

    【讨论】:

    • 感谢您的快速回答,它有效。你能评论它有多准确吗?我已经阅读了关于 time.time 和 time.clock 的内容,并且 time.clock 似乎更适合我的情况(对于 Windows)。但是我不确定我的结果有多可靠。我正在为视觉测试做同样的事情,只是改变了背景。收到播放声音的命令和播放实际声音之间是否有延迟?它与更改背景时的延迟有显着不同吗?谢谢
    • 我尝试使用timeit来验证。只包括 winsound.PlaySound... 声明就足够了吗?我运行了几次,但我发现声音本身的持续时间包含在我的时间中。我应该找出那个声音有多长然后减去它吗?那么垃圾收集呢?我不确定是否应该启用它。
    • @user1830663:我认为测量延迟将非常困难,甚至是不可能的,尤其是在 Python 内部,因为它涉及到它之外的组件在做事。最好的办法是获得一些经验测量值。
    猜你喜欢
    • 1970-01-01
    • 2015-05-01
    • 1970-01-01
    • 2022-08-05
    • 1970-01-01
    • 2013-03-27
    • 2016-12-22
    • 1970-01-01
    相关资源
    最近更新 更多