Python Tkinter:当主应用程序最小化时,进度条不会最小化 [英] Python Tkinter: Progress bar does not get minimized when main application gets minimized

查看:79
本文介绍了Python Tkinter:当主应用程序最小化时,进度条不会最小化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请运行以下示例.

我为我的应用程序创建了一个进度条,按下打开"按钮会弹出一个进度条.但是,当主应用程序最小化时,进度条不会最小化.

I have created a progress bar for my application, and by pressing the "Open" button a progress bar pops up. However, the progress bar does not get minimized when main application gets minimized.

我已经尝试了以下代码行,但它只有在我注释掉 self.master.overrideredirect(True) 时才有效:

I have tried the following line of code, but it only works if I comment out self.master.overrideredirect(True):

self.master.transient(parent)

示例(Python 2.7.3、Linux、Tkinter 版本 $Revision: 81008 $):

Example (Python 2.7.3, Linux, Tkinter version $Revision: 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()

推荐答案

您可以设置自己的绑定来管理覆盖重定向窗口的可见性.当小部件被图标化或取消图标化时,Tkinter 会生成事件 .因此,向主窗口添加绑定以在弹出窗口中调用 wm_deiconifywithdraw.

You can set up your own binding to manage the visibility of the overrideredirect-ed window. Tkinter generates the events <Map> and <UnMap> when a widget is iconified or un-iconified. So, add bindings to the main window to call either wm_deiconify or withdraw on the popup window.

这篇关于Python Tkinter:当主应用程序最小化时,进度条不会最小化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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