如何阻止python点击事件再次触发,直到第一个事件完成



在python上使用鼠标点击事件时,会同时发生多次点击。这使得循环在处理不断变化的变量时出现问题。

我想单线程处理它。停止点击事件,直到该线程中的所有功能都完成,然后收听更多信息。

我也不知道为什么我一次点击了多次。每次我点击,它就会触发3次。这就是为什么我想提出这个问题来解决这个问题。

这是我的代码

import matplotlib.pyplot as plt
from matplotlib.offsetbox import TextArea, DrawingArea, OffsetImage, AnnotationBbox
import matplotlib.image as mpimg
import numpy as np
from mpl_point_clicker import clicker

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def isAround(self, anotherPoint):
        if anotherPoint.x == self.x + 1 or anotherPoint.x == self.x - 1 or anotherPoint.x == self.y + 1 or anotherPoint.x == self.y - 1:
            return True
        return False
    def roundPoints(self):
        self.x = round(self.x, 2)
        self.y = round(self.y, 2)
            

mouseClicks = []
slopeAndLengths = []
count = 0

def on_pick(event):
    global count
    artist = event.artist
    xmouse, ymouse = event.mouseevent.xdata, event.mouseevent.ydata
    x, y = artist.get_xdata(), artist.get_ydata()
    ind = event.ind
    # print ('Artist picked:', event.artist)
    # print ('{} vertices picked'.format(len(ind)))
    print ('Pick between vertices {} and {}'.format(min(ind), max(ind)+1))
    # print ('x, y of mouse: {:.2f},{:.2f}'.format(xmouse, ymouse))
    # print ('Data point:', x[ind[0]], y[ind[0]])
    # print(" ------------------- ")
    thisPoint = Point(x[ind[0]], y[ind[0]])
    thisPoint.roundPoints()
    mouseClicks.append(thisPoint)
    for i in range(len(mouseClicks)):
        for j in list(range(len(mouseClicks))):
            if mouseClicks[i].isAround(mouseClicks[j]):
                if not mouseClicks[i] == mouseClicks[j]:
                    mouseClicks.pop(i)
    print(mouseClicks)
    # mouseClicks.append((round(x[ind[0]],2),round(y[ind[0]],2)))
    # count += 1
    # if count % 2 == 0:
    #     mouseClicks.pop()
    #     print(mouseClicks)
    
    if len(mouseClicks)==2:
        length = mouseClicks[1].x - mouseClicks[0].x
        slope = (mouseClicks[1].y - mouseClicks[0].y)/(mouseClicks[1].x - mouseClicks[0].x)
        slopeAndLengths.append((round(slope,2),round(length,2)))
        mouseClicks.pop(0)
        # print(slopeAndLengths)
        # print(mouseClicks)
    # addPoint(round(x[ind[0]],2),round(y[ind[0]],2))
    # ax.plot(round(x[ind[0]],2),round(y[ind[0]],2),'bo-', zorder=2)
    # plt.draw()
    
arr_lena = mpimg.imread('picture.png')
imageBox = OffsetImage(arr_lena, zoom=2)
ab = AnnotationBbox(imageBox, (7.4, 13.6), zorder=1)

fig, ax = plt.subplots()
ax.add_artist(ab)
for row in range(1,30):
    tolerance = 30 # points
    ax.plot(np.arange(0,15,0.5),[i*row/i for i in range(1,15*2+1)], 'ro-', picker=tolerance, zorder=0)

fig.canvas.callbacks.connect('pick_event', on_pick)
klicker = clicker(ax, ["event"], markers=["x"], **{"linestyle": "--"})

plt.draw()
plt.savefig('add_picture_matplotlib_figure.png',bbox_inches='tight')
plt.show()

我尝试过这个想法来删除第一个接收点附近的点,但因为多个线程同时发生,所以这没有帮助。

for i in range(len(mouseClicks)):
        for j in list(range(len(mouseClicks))):
            if mouseClicks[i].isAround(mouseClicks[j]):
                if not mouseClicks[i] == mouseClicks[j]:
                    mouseClicks.pop(i)

我是如何修复它的:

在我找到答案之前,我们知道每次收到点击时,on_pick函数都会运行。因此,利用时间,我可以忽略同时发生的事件火灾,只留下其中一个。

答案:

Before = datetime.now()
def on_pick(event):
    global Before
    now = datetime.now()
    if (now < Before + timedelta(seconds=1)):
        return
    Before = datetime.now()
    ...

最新更新