2013-07-24 95 views
1

我正在編寫一個程序,它執行一些工作並使用matplotlib來繪製一些數據。這可能需要一些時間,所以我使用tkinter設置了一個進度條。用tkinter進行線程化並不那麼容易。我正在主線程中運行進度條,並在基本線程中運行我的工作內容。但是我的工作完成後我無法關閉進度條窗口,因爲matplotlib在tk根窗口中執行了某些操作。我不知道是什麼。我添加了一個我正在嘗試做的最簡單的例子。注意,刪除「plotsomething()」這一行使得它可以做我想做的事情:完成工作後關閉進度條。當matplotlib窗口打開時關閉tkinter進度條窗口

你能幫我弄清楚如何關閉進度條窗口而不關閉matplotlib窗口嗎?

# 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後端seperatly繪製每一個窗口,現在解決這個問題。顯然PyPlot正在干擾tkinter根窗口。有關更多細節和提示,請參閱tcaswell的評論。非常感謝你!

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

所以,你要的進度在啓動時啓動,數到10,打印 「完成」,破壞本身,那麼matplotlib窗口會正確啓動? – iCodez

+0

作爲一個側面問題,您希望在文檔中查找哪些內容以找到它?這個問題每隔一週以各種形式出現,這表明文檔失敗。 – tacaswell

+0

再次看到這個問題,你真的應該發佈你的編輯作爲答案。爲了憤世嫉俗,我代表我的一半答案,你應該得到你的完整答案;) – tacaswell

回答

2

你所得到的TK你開始和TKplt是啓動之間衝突的圖形用戶界面的主迴路。如果你想用你自己的gui使用matplotlib,你需要嵌入它你自己和你不能進口pyplot。所有的幕後魔法讓界面變得美好,這就是你在這裏搞砸了什麼。

有關教程,請參見herempl的嵌入方式請參閱here

另見: