2015-09-25 88 views
0

ProgressDialog類允許通過選項wx.PD_CAN_ABORT,其中 添加一個「取消」按鈕到對話框。我需要重新綁定與此 按鈕綁定的事件,以使其成爲Destroy()對話框而不是僅僅「按照類的文檔描述的使下一個呼叫 Update()[返回False]」。如何覆蓋ProgressDialog的「取消」按鈕事件?

class PortScanProgressDialog(object): 

    """Dialog showing progress of the port scan.""" 

    def __init__(self): 
     self.dialog = wx.ProgressDialog(
      "COM Port Scan", 
      PORT_SCAN_DLG_MSG, 
      MAX_COM_PORT, 
      style=wx.PD_CAN_ABORT | wx.PD_AUTO_HIDE) 

    def get_available_ports(self): 
     """Get list of connectable COM ports. 

     :return: List of ports that e.g. exist, are not already open, 
      that we have permission to open, etc. 
     :rtype: list of str 
     """ 
     com_list = [] 
     keep_going = True 
     progress_count = 0 
     for port_num in range(MIN_COM_PORT, MAX_COM_PORT + 1): 
      if not keep_going: 
       break 
      port_str = "COM{}".format(port_num) 
      try: 
       # Check if the port is connectable by attempting to open 
       # it. 
       t_port = Win32Serial(
        port_str, COMPATIBLE_BAUDRATE, 
        bytesize=SerialThread.BYTESIZE, 
        parity=SerialThread.PARITY, 
        stopbits=SerialThread.STOPBITS, timeout=4) 
       t_port.close() 
       com_list.append(port_str) 
      finally: 
       progress_count += 1 
       # This returns a tuple with 2 values, the first of which 
       # indicates if progress should continue or stop--as in 
       # the case of all ports having been scanned or the 
       # "Cancel" button being pressed. 
       keep_going = self.dialog.Update(progress_count, msg)[0] 
     return com_list 

此類以這種方式在其他地方使用:

# Scan for available ports. 
port_scan_dlg = PortScanProgressDialog() 
ports = port_scan_dlg.get_available_ports() 
port_scan_dlg.dialog.Destroy() 

當未處理的異常在get_available_ports()出現進度 對話將保持打開狀態(這是預期的行爲),但問題是, 當我點擊「取消」時,按鈕變灰,窗口未關閉(單擊 「X」也無法關閉窗口)。

我在嘗試將「取消」按鈕重新綁定到Destroy()的 對話框。我怎樣才能做到這一點?

我知道這workaround,但我認爲它更清潔使用ProgressDialog 並修改它以滿足我的需要。

回答

1

「取消」按鈕不直接顯示在此小部件中。您可以使用對話框的GetChildren方法進行操作。下面是做這件事:

import wx 

class TestPanel(wx.Panel): 
    def __init__(self, parent): 
     wx.Panel.__init__(self, parent, -1) 

     b = wx.Button(self, -1, "Create and Show a ProgressDialog", (50,50)) 
     self.Bind(wx.EVT_BUTTON, self.OnButton, b) 


    def OnButton(self, evt): 
     max = 80 

     dlg = wx.ProgressDialog("Progress dialog example", 
           "An informative message", 
           maximum = max, 
           parent=self, 
           style = wx.PD_CAN_ABORT 
           | wx.PD_APP_MODAL 
           | wx.PD_ELAPSED_TIME 
           #| wx.PD_ESTIMATED_TIME 
           | wx.PD_REMAINING_TIME 
           ) 
     for child in dlg.GetChildren(): 
      if isinstance(child, wx.Button): 
       cancel_function = lambda evt, parent=dlg: self.onClose(evt, parent) 
       child.Bind(wx.EVT_BUTTON, cancel_function) 

     keepGoing = True 
     count = 0 

     while keepGoing and count < max: 
      count += 1 
      wx.MilliSleep(250) # simulate some time-consuming thing... 

      if count >= max/2: 
       (keepGoing, skip) = dlg.Update(count, "Half-time!") 
      else: 
       (keepGoing, skip) = dlg.Update(count) 


     dlg.Destroy() 

    #---------------------------------------------------------------------- 
    def onClose(self, event, dialog): 
     """""" 
     print "Closing dialog!" 


######################################################################## 
class MyFrame(wx.Frame): 
    """""" 

    #---------------------------------------------------------------------- 
    def __init__(self): 
     """Constructor""" 
     wx.Frame.__init__(self, None, title='Progress') 
     panel = TestPanel(self) 
     self.Show() 

if __name__ == '__main__': 
    app = wx.App(False) 
    frame = MyFrame() 
    app.MainLoop() 

這是基於這種特殊的對話框wxPython的演示例子。根據您的平臺,您將獲得本地小部件(如果存在),否則您將獲得wx.GenericProgressDialog。我懷疑本地小部件不會允許您訪問取消按鈕,但我不確定。