我有一个绘图,允许用户点击一个数据点。然后,它生成一个连续的循环,该循环应该通过单击close按钮来关闭。下面的示例将每1秒触发一条“仍在循环”的打印消息。然后我创建了一个按钮,希望通过将loopBool更改为True来关闭循环。但它不起作用,因为一旦循环开始,我就无法与图形窗口交互。我怎么解决这个问题?非常感谢
import numpy as np
from matplotlib import pyplot as plt
import time
import matplotlib.widgets as widgets
fig, ax = plt.subplots()
# it is not always column 0 and 1
sctPlot = ax.scatter([-0.3,0,0.3], [0.3,0.3,0.3], c="blue", picker = 2, s=[50]*3)
fig.subplots_adjust(bottom=0.3, left=0.1)
plt.grid(False)
plt.axis([-0.6, 0.6, -0.6, 0.6])
loopBool = True
def closeLooping(event):
global loopBool
loopBool = False
def looping(event):
global loopBool
while (loopBool == True):
print "Still Looping!"
time.sleep(1)
print "Stop!!"
axCloseButton = plt.axes([0.1, 0.15, 0.2, 0.06])
bClose = Button(axCloseButton, "Close", color = axcolor, hovercolor = '0.975')
bClose.on_clicked(closeLooping)
fig.canvas.mpl_connect('pick_event', looping)
在我看来,陷入无限循环的进程在某种意义上与GUI不兼容。gui本身执行一个循环,检查并响应发生的事件。最好的解决方案可能是删除无限循环,将该部分代码转换为基于事件的循环。在
不过,我也找到了解决你实际问题的办法。我不太熟悉所涉及的编程结构,所以我不能告诉您这个解决方案有多高效或优雅。关键是在一个单独的线程中运行无限循环,从而防止主python进程陷入循环中。这将使GUI保持响应。但是,如果您想在程序运行期间中断程序,这可能会导致问题。在
代码:
请注意,我更改了一些事情,因为您的代码似乎无法正常运行。我从
Button
调用中删除了color=axcolor
;并且在事件连接之前添加了一个plt.show()
,否则我不会出现一个图窗口(既不是通过ipython
,也不是通过python
)出现的。在相关的添加是
threading
模块和looping_pre
前端,它将looping
函数作为一个单独的Thread
调用。因此,'pick_event'
不调用looping
,而是looping_pre
。在这段代码将(在
ipython
中运行时)显示figure窗口,在单击数据时开始循环,然后在单击按钮时停止循环。但是,当我按下ctrl+c时,循环继续进行,因为它是一个单独的线程。我只是通过使用reset
来杀死它,从而删除了global loopBool
的值。指定Thread
是否应为deamon
的注释行应影响此行为(我的意思是它在我看来是合乎逻辑的),但我没有看到任何效果。在相关问题 更多 >
编程相关推荐