2014-09-26 65 views
0

请运行以下示例。Python Tkinter:当主应用程序最小化时,进度条没有被最小化

我为我的应用程序创建了一个进度条,并通过按下“打开”按钮弹出一个进度条。但是,当主应用程序最小化时,进度条并未最小化。

我曾尝试下面的代码行,但如果我注释掉self.master.overrideredirect(真),它仅适用:

self.master.transient(parent) 

示例(Python 2.7.3,Linux的,Tkinter的版本$修订:81008 $):

from Tkinter import Tk, Frame, BOTH, Label, Toplevel, Canvas, Button 
import threading 

class ProgressBar: 
    def __init__(self, parent, width, height): 
     master = Toplevel(parent) 
     master.protocol('WM_DELETE_WINDOW', self.hide) 
     self.master = master 
     self.master.overrideredirect(True) 
     ws = self.master.winfo_screenwidth() 
     hs = self.master.winfo_screenheight() 
     w = (True and ws*0.2) or 0.2 
     h = (True and ws*0.15) or 0.15 
     x = (ws/2) - (w/2) 
     y = (hs/2) - (h/2) 
     self.master.geometry('%dx%d+%d+%d' % (width, height * 2.5, x, y)) 

     self.mode = 'percent' 
     self.ONOFF = 'on' 
     self.width = width 
     self.height = height 
     self.frame = None 
     self.canvas = None 
     self.progressBar = None 
     self.backgroundBar = None 
     self.progressformat = 'percent' 
     self.label = None 
     self.progress = 0 

     self.createWidget() 
     self.frame.pack() 
     self.set(0.0)     # initialize to 0% 

     #self.master.transient(parent) 
    def createWidget(self): 
     self.frame = Frame(self.master, borderwidth = 1, relief = 'sunken') 
     self.canvas = Canvas(self.frame) 
     self.backgroundBar = self.canvas.create_rectangle(0, 0, self.width, self.height, fill = 'darkblue') 
     self.progressBar = self.canvas.create_rectangle(0, 0, self.width, self.height, fill = 'blue') 
     self.setWidth() 
     self.setHeight() 
     self.label = Label(self.frame, text = 'Loading...', width = 20) 
     self.label.pack(side = 'top') # where text label should be packed 
     self.canvas.pack() 
    def setWidth(self, width = None): 
     if width is not None: 
     self.width = width 
     self.canvas.configure(width = self.width) 
     self.canvas.coords(self.backgroundBar, 0, 0, self.width, self.height) 
     self.setBar() # update progress bar 
    def setHeight(self, height = None): 
     if height is not None: 
     self.height = height 
     self.canvas.configure(height = self.height) 
     self.canvas.coords(self.backgroundBar, 0, 0, self.width, self.height) 
     self.setBar() # update progress bar 
    def set(self, value): 
     if self.ONOFF == 'off': # no need to set and redraw if hidden 
     return 
     if self.mode == 'percent': 
     self.progress = value 
     self.setBar() 
     return 
    def setBar(self): 
     self.canvas.coords(self.progressBar,0, 0, self.width * self.progress/100.0, self.height) 
     self.canvas.update_idletasks() 
    def hide(self): 
     if isinstance(self.master, Toplevel): 
     self.master.withdraw() 
     else: 
     self.frame.forget() 
     self.ONOFF = 'off' 
    def configure(self, **kw): 
     mode = None 
     for key,value in kw.items(): 
     if key=='mode': 
      mode = value 
     elif key=='progressformat': 
      self.progressformat = value 
     if mode: 
     self.mode = mode 
def ProgressBarLoop(window, bar, i = 0, direction = "a"): 
    bar.configure(mode = 'percent', progressformat = 'ratio') 
    if not window.loading: 
     bar.hide() 
     return 
    bar.set(i) 
    if direction == "a": 
     i += 1 
    else: 
     i -= 1 
    if i == 101: 
     direction = "d" 
    elif i == 0 and direction == "d": 
     direction = "a" 
    window.parent.after(1, ProgressBarLoop, window, bar, i, direction) 

class Application(Frame): 
    def __init__(self, parent): 
     Frame.__init__(self, parent) 
     self.parent = parent 
     self.pack(fill = BOTH, expand = True) 
     parent.geometry('%dx%d+%d+%d' % (100, 100, 0, 0)) 
     Button(parent, text = "Open", command = self.onOpen).pack() 
    def onOpen(self, event = None): 
     self.loading = True 
     bar = ProgressBar(self, width=150, height=18) 
     t = threading.Thread(target=ProgressBarLoop, args=(self, bar)) 
     t.start() 
root = Tk() 
Application(root) 
root.mainloop() 
+0

在询问有关Tkinter或Tk行为的一般问题时,您应该准确包括Tk的版本以及您使用的Tk版本,因为Tk的行为因平台和版本而异。 – 2014-09-26 23:19:20

+0

感谢您的支持! – 2014-09-26 23:31:35

回答

0

您可以设置自己的绑定来管理overrideredirect-ed窗口的可见性。当小部件被图标化或未被图标化时,Tkinter生成事件<Map><UnMap>。因此,在主窗口中添加绑定,在弹出窗口中调用wm_deiconifywithdraw

+0

这太棒了!谢谢! – 2014-10-02 00:54:02