在 matplotlib 窗口打开时关闭 tkinter 进度条窗口 [英] Close a tkinter progressbar window while matplotlib window is open

查看:88
本文介绍了在 matplotlib 窗口打开时关闭 tkinter 进度条窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个程序来完成一些工作并使用 matplotlib 绘制一些数据.这可能需要一些时间,所以我使用 tkinter 设置了一个进度条.使用 tkinter 进行线程处理并不容易.我在主线程中运行进度条,在子线程中运行我的工作内容.但是,我的工作完成后我无法关闭进度条窗口,因为显然 matplotlib 在 tk 根窗口中做了一些事情.我不知道什么我添加了一个我正在尝试做的最小示例.请注意,删除plotsomething()"行使其执行我想要的操作:完成工作后关闭进度条.

I am writing a program that does some work and uses matplotlib to plot some data. This can take some time so I set up a progressbar using tkinter. Threading with tkinter was not that easy. I am running the progressbar in the main thread and my working stuff in a substhread. However I can not close the progressbar window after my work is done, because apparently matplotlib does something in the tk root window. I don't know what. I added a minimal example of what I am trying to do. Notice that removing the line "plotsomething()" makes it do what I want: close the progressbar after work is done.

你能帮我弄清楚如何在不关闭 matplotlib 窗口的情况下关闭进度条窗口吗?

Can you please help me figuring out how I can close the progressbar window without closing the matplotlib windows?

# coding = utf-8
import numpy as np
import matplotlib.pyplot as plt
import tkinter as tk
from tkinter import ttk
import threading, queue
import time

def MAIN():
    PB = q.get()
    for i in np.arange(10):
        time.sleep(0.2)
        print(i)
        PB.step(10)
        PB.update()
    print("Done")

def plotsomething():
    x = np.linspace(0,10,100)
    y = np.sin(x)
    plt.plot(x,y)

root = tk.Tk()
root.title("Progress")
PB = ttk.Progressbar(root, orient = "horizontal",length=300, mode = 'determinate')
PB.pack()
q = queue.Queue()
q.put(PB)

plotsomething()

T = threading.Thread(target=MAIN(), name="MAIN")
T.start()
T.join()
plt.show()

编辑 - 解决方案:我现在通过使用 matplotlib tk 后端单独绘制每个窗口来解决问题.显然 PyPlot 正在干扰 tkinter 根窗口.有关更多详细信息和提示,请参阅 tcaswell 的评论.非常感谢!

EDIT - SOLUTION: I am solving the problem now by drawing every window seperatly by using the matplotlib tk backend. Apparently PyPlot is interfering with the tkinter root windows. See tcaswell's comment for more details and hints. Thank you very much!

import numpy as np
import matplotlib
matplotlib.use('TkAgg')

from numpy import arange, sin, pi
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import tkinter as tk
from tkinter import ttk
import queue, threading, time

def center_window(window_parent, w=300, h=20):
    # get screen width and height
    ws = window_parent.winfo_screenwidth()
    hs = window_parent.winfo_screenheight()
    # calculate position x, y
    x = (ws/2) - (w/2)
    y = (hs/2) - (h/2)
    window_parent.geometry('%dx%d+%d+%d' % (w, h, x, y))

def MAIN():
    PB = q.get()
    for i in np.arange(10):
        time.sleep(0.2)
        print(i)
        PB.step(10)
        PB.update()
    print("Done")

root = tk.Tk()
root.wm_title("Embedding in TK")


f = Figure(figsize=(5,4), dpi=100)
a = f.add_subplot(111)
t = arange(0.0,3.0,0.01)
s = sin(2*pi*t)

a.plot(t,s)
a.set_title('Tk embedding')
a.set_xlabel('X axis label')
a.set_ylabel('Y label')


#a tk.DrawingArea
root2 = tk.Tk()

PB = ttk.Progressbar(root2, orient = "horizontal",length=300, mode = 'determinate')
PB.pack()

canvas = FigureCanvasTkAgg(f, master=root)
canvas.show()
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)

toolbar = NavigationToolbar2TkAgg( canvas, root )
toolbar.update()
canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)

root2.iconify()
root2.update()
root2.deiconify()

center_window(root2)

q = queue.Queue()
q.put(PB)

T = threading.Thread(target=MAIN(), name="MAIN")
T.start()
T.join()

root2.quit()
root2.destroy()

tk.mainloop()

推荐答案

您正在启动的 TKTK 之间出现冲突的 gui-main 循环code>plt 是开始.如果您想将 matplotlib 与您自己的 gui 一起使用,您必须将其嵌入您自己,并且您不能导入 pyplot.让 pyplot 界面变得美妙的所有幕后魔法都让你在这里搞砸了.

You are getting conflicting gui-main loops between the TK you are starting and the TK that plt is start. If you want to use matplotlib with your own gui, you must embed it your self and you can not import pyplot. All the behind the scenes magic that makes the pyplot interface wonderful is what is messing you up here.

有关教程,请参阅此处,了解如何mpl 嵌入是否参见此处.

For a tutorial see here, for how mpl does the embedding see here.

另见:

这篇关于在 matplotlib 窗口打开时关闭 tkinter 进度条窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆