【问题标题】:Close a tkinter progressbar window while matplotlib window is open在 matplotlib 窗口打开时关闭 tkinter 进度条窗口
【发布时间】:2013-07-23 21:38:02
【问题描述】:

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

你能帮我弄清楚如何在不关闭 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 后端分别绘制每个窗口来解决问题。显然 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()

【问题讨论】:

  • 所以你想让进度条在启动时启动,数到 10,打印“完成”,销毁自己,然后 matplotlib 窗口会启动对吗?
  • 作为一个附带问题,您希望在文档中的哪个位置找到它?这个问题每隔一周就会以各种形式出现,这表明存在文档失败。
  • 又看了一遍这个问题,你真的应该发布你的编辑作为答案。愤世嫉俗的是,我的半答案得到了代表,你应该得到完整的答案;)

标签: python matplotlib plot tkinter


【解决方案1】:

您正在启动的 TK 和启动 pltTK 之间出现冲突的 gui-main 循环。如果您想将matplotlib 与您自己的gui 一起使用,您必须 自己嵌入它并且您不能 导入pyplot。使pyplot 界面精彩的所有幕后魔法都是让您感到困惑的原因。

教程见herempl如何嵌入见here

另见:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多