wxpython:destroy取消了ProgressDialog

时间:2016-09-20 00:51:58

标签: wxpython

我无法关闭wx.ProgressDialog。如果它到期;一切都好。单击取消或跳过将突破对话框,但窗口将永久冻结在屏幕上(控制流返回)。

import wx
def Progress(parent=None, message="", title="", maximum=3000):
  dlg = wx.GenericProgressDialog(title, message, maximum,style=wx.PD_AUTO_HIDE|wx.PD_APP_MODAL|wx.PD_CAN_SKIP|wx.PD_CAN_ABORT)
  keepGoing = True
  skip = False
  count = 0

  while keepGoing and (not skip) and count < maximum:
      count += 1
      wx.MilliSleep(1)
      wx.Yield()
      (keepGoing, skip_bogus) = dlg.Update(count)
      skip = dlg.WasSkipped()  #NOTE:  skip_bogus doesn't ever seem to update; even when skip button is clicked

  dlg.Destroy()
  wx.Yield()

  if not keepGoing:
      return "cancel"
  elif skip:
      return "skip" 
  else:
      return None

app = wx.App()
app.MainLoop()

Progress(None, "message", "title")

wxpython v3.0.2 python v2.7.10

3 个答案:

答案 0 :(得分:1)

它可能在某种程度上取决于平台,但在Progress返回后调用MainLoop函数对我来说是一个红旗。调用Destroy方法时,顶级窗口不会被销毁,而是将它们添加到待处理的删除队列中,该队列稍后将在事件循环中处理。

尝试在Process来电前致电MainLoop,并在wx.Yield之后移除对Destroy的来电。这对OSX和凤凰城来说很有用。

答案 1 :(得分:0)

这是LongRunningTask的经典示例:您的while循环将耗尽所有不用于事件处理的时间。当事件开始堆积时,GUI无法响应,并且wxPython不再能够及时处理任何事件(或处理对wx.Yield()的调用)。

该问题的解决方案是将阻塞事件/长时间运行任务放在一个单独的线程中,并使用e回调到GUI线程安全。 G。工作完成后wx.CallAfter

研究上面给出的链接中的最后一个示例,Easiest Example *ever* :)以了解如何执行此操作。

答案 2 :(得分:0)

Robin和nepix32的答案是有价值的建议。另外,为什么不使用wx.Timer来不断更新对话框?类似的东西:

class Progress:
    def __init__(self):
        self.dlg = wx.GenericProgressDialog(whatever)
        self.count = 0

    def Start(self):
        self._update()
        self.timer = wx.Timer(self.dlg)
        self.dlg.Bind(wx.EVT_TIMER, self._update, self.timer)
        self.timer.Start(1) # 1ms interval

    def _update(self, evt=None):
        self.count += 1
        if self.count == self.dlg.GetRange():
            self._stop()
        else:
            self.dlg.Update(self.count)
            if self.dlg.WasSkipped() or self.dlg.WasCancelled():
                self._stop()

    def _stop(self):
        self.timer.Stop()
        self.dlg.Close()
        wx.GetApp().ExitMainLoop()

您的问题的答案 - 如何关闭对话框 - 是wx.GetApp().ExitMainLoop()