Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
665 views
in Technique[技术] by (71.8m points)

python - Close a tkinter progressbar window while matplotlib window is open

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.

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

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()
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

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

Also see:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...