【问题标题】:Single mouse click within While loop (PsychoPy)在 While 循环中单击鼠标 (PsychoPy)
【发布时间】:2014-04-16 14:43:41
【问题描述】:

我正在使用 PsychoPy,我想打印鼠标被点击时的位置。

位置的实际打印需要放在一个while循环中。使用下面的代码,当我单击时,我得到多个输出行,它们打印相同的位置。我希望每次点击只打印一个输出。

这是我正在使用的代码:

#!/usr/bin/env python2
from psychopy import visual, core, event
from pyglet.gl import *

width = 600
height = 600
myWin = visual.Window([width,height], color='white',units='pix',monitor='testMonitor')

#This will set the windows units (pixels) to GL units
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0, width, 0, height, -1, 1)

glMatrixMode(GL_MODELVIEW)
glLoadIdentity()

glEnable(GL_BLEND)
glBlendFunc(GL_ZERO, GL_SRC_COLOR)

myMouse = event.Mouse()  #  will use myWin by default


while True:
    #Triangle left
    glColor3f(1.0, 0.0, 0.0)
    glBegin(GL_TRIANGLES)
    glVertex3f(150, 550, 1)
    glVertex3f(50, 350, 1)
    glVertex3f(250, 350, -1)
    glEnd()

    if myMouse.getPressed()[0]:
        myMouse.clickReset()
        print myMouse.getPos()

    myWin.flip()

core.quit()

我做错了什么吗? while 循环的“帧率”是否应该改变?

【问题讨论】:

    标签: python while-loop mouseevent psychopy


    【解决方案1】:

    我没有使用过该模块,但似乎鼠标事件也被引发了鼠标raises

    你需要

    • 保存鼠标状态以备下次使用

    • 每次迭代,测试按钮0的鼠标状态是否向上→向下

    鼠标状态由myMouse.getPressed返回。

    比如:

    oldMouseIsDown = False
    
    while True:
        ...
    
        mouseIsDown = myMouse.getPressed()[0]
        myMouse.clickReset()
    
        if mouseIsDown and not oldMouseIsDown:
            print myMouse.getPos()
    
        oldMouseIsDown = mouseIsDown
    

    【讨论】:

    • 感谢您的回答 Veedrac。我认为鼠标抬起不是问题,因为这样当我单击时,我只会得到两个打印件(第一个用于向上->向下,第二个用于向下->向上)。目前,当我单击时,我会打印四到五次,而当我快速单击并抬起手指时,我只会得到我想要的一次打印。无论如何,我会尝试寻找这些加薪,看看我能做些什么。
    • 好的,这说明了一切。如果删除 myMouse.clickReset() 会发生什么?
    • 没什么。如果我删除myMouse.clickReset(),结果是完全一样的。
    【解决方案2】:

    维德拉克的回答是正确的。您的代码使用了典型的 PsychoPy 模式,每次重绘窗口时都会检查一次事件。这通常会在至少 60 Hz 时发生。因此,除非您设法按下鼠标按钮少于 16.7 毫秒(或更短的时间以获得更快的屏幕),否则您将多次检测到它被按下,因为每次检查连续的窗口重绘时,鼠标按钮都会保持按下状态。即使只推送了一次,推送的持续时间也不是瞬时的。

    正如 Veedrac 建议的那样,因此您需要在变量中维护鼠标按钮的先前状态,以便您可以选择只打印一次位置。 Mouseup 事件在这里不相关:您只是在测试当前是否按下了按钮。

    【讨论】:

      【解决方案3】:

      我遇到了一个非常相似的问题,并以与接受的答案略有不同的方式解决了它。这个的优点是您可以设置单击后要“脱敏”鼠标多长时间(即防止较长时间的单击多次触发您的 if 循环)。根据您的鼠标或用户的点击释放速度,您可以更改minFramesAfterClick

      minFramesAfterClick = 10 # to prevent re-entering the if loop too early
      myMouse.clickReset()
      timeAfterClick = 0
      while True:
          timeAfterClick += 1
          if myMouse.getPressed()[0] and timeAfterClick >= minFramesAfterClick:
               print myMouse.getPos()
               myMouse.clickReset()
               timeAfterClick = 0
          myWin.flip()
      

      顺便说一句,OP 无法获得 Veedrac 的答案的原因是因为应该将行 oldMouseIsDown = mouseIsDown 放在 if 循环中而不是在它之后(没有足够的声誉在那里发表评论)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-15
        • 1970-01-01
        • 1970-01-01
        • 2021-05-05
        相关资源
        最近更新 更多