Python pyplot首次显示/关闭图形后缺少第一个事件

Python pyplot首次显示/关闭图形后缺少第一个事件,python,matplotlib,event-handling,imshow,Python,Matplotlib,Event Handling,Imshow,我试图在matplotlib图中迭代一系列图像,并为每个图像记录一系列事件(鼠标单击和按键)。然而,在第一个数字之后,第一个事件就被错过了 例如,在以下MLE中,如果用户在显示第一个图像后按“q”,则会显示第二个图像。但是,如果用户再次按“q”,则事件将丢失,并且在关闭第二个图像之前,他们必须第三次按“q” from numpy import * from matplotlib import pyplot as plt from matplotlib.pyplot import figure,

我试图在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()