1

我正在使用 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 循环的“帧速率”?

4

3 回答 3

3

我没有使用过该模块,但似乎鼠标事件也会引发鼠标提升

你需要

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

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

鼠标状态由myMouse.getPressed.

所以像:

oldMouseIsDown = False

while True:
    ...

    mouseIsDown = myMouse.getPressed()[0]
    myMouse.clickReset()

    if mouseIsDown and not oldMouseIsDown:
        print myMouse.getPos()

    oldMouseIsDown = mouseIsDown
于 2014-04-16T14:55:43.650 回答
3

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

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

于 2014-05-02T09:34:24.143 回答
2

我有一个非常相似的问题,并以与接受的答案略有不同的方式修复它。这样做的好处是您可以设置您希望在单击后多长时间使鼠标“脱敏”(即防止较长时间的单击多次触发您的 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 的答案的原因是因为 lineoldMouseIsDown = mouseIsDown应该放在 if 循环内而不是在它之后(没有足够的声誉在那里发表评论)。

于 2015-02-23T04:56:59.790 回答