在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()
...