我正在尝试在 matplotlib 图形中迭代一系列图像,并为每个图像记录一系列事件(鼠标单击和按键)。但是,在第一个数字之后,第一个事件被错过了。
例如,在下面的 MLE 中,如果用户在显示第一个图像后按"q",则会显示第二个图像。但是,如果用户再次按"q",则会错过事件,并且他们必须在关闭第二个图像之前第三次按"q"。
from numpy import *
from matplotlib import pyplot as plt
from matplotlib.pyplot import figure, show, draw
class guiBackend:
def __init__(self, srcImage):
self.srcImage = srcImage
self.fig = figure(figsize=(16,16), frameon=False)
self.axSrc = self.fig.add_subplot(111, autoscale_on=True)
self.showObj = self.axSrc.imshow(self.srcImage)
self.cidKey = self.fig.canvas.mpl_connect('key_press_event', self.pressButton)
def pressButton(self, event):
if event.key == 'q':
self.fig.canvas.mpl_disconnect(self.cidKey)
plt.close(self.fig)
return
else:
self.srcImage = random.randint(0, 256, size=(128,128,3))
self.showObj.set_data(self.srcImage)
self.fig.canvas.draw()
def main():
for k in xrange(2):
img = random.randint(0, 256, size=(128,128,3))
imgObj = guiBackend(img)
plt.show()
return 1
从我收集到的信息来看,这是由于多次调用show()
和close()
但我找不到另一种方法来在循环的每次迭代期间阻止程序,以便收集一系列用户输入,直到用户按"q"。
我无法重现运行(某种)1.5.x分支的问题(缺少事件)。 至于你的第二个问题,我建议通过生成器将循环注入到 gui 处理代码中:
import numpy as np
from matplotlib import pyplot as plt
class guiBackend:
def __init__(self, img_gen):
self.img_gen = iter(img_gen)
self.cur_image = next(self.img_gen)
self.fig = plt.figure(figsize=(16, 16), frameon=False)
self.axSrc = self.fig.add_subplot(111, autoscale_on=True)
self.im = self.axSrc.imshow(self.cur_image)
self.cidKey = self.fig.canvas.mpl_connect('key_press_event',
self.button_press)
def button_press(self, event):
print("in handler")
print('got key {}'.format(event.key))
if event.key == 'q':
try:
self.cur_image = next(self.img_gen)
except StopIteration:
plt.close(self.fig)
return
self.im.set_data(self.cur_image)
self.fig.canvas.draw_idle()
def image_gen(n):
for k in range(n):
yield np.random.randint(0, 256, size=(128, 128, 3))
# need to hold on to this or callback gets gc'd
gui_backend = guiBackend(image_gen(5))
plt.show()