2016-12-12 32 views
0

我正在爲esptool.py開發wxPython GUI,即應用程序將調用該腳本。對於初學者,我想將esptool.py打印的內容重定向到控制檯到TextCtrl。爲此,我遵循frequently referenced article,效果很好。如何持續更新(終端式)wxPython TextCtrl

但是,我目前堅持處理progress monitor that esptool.py prints to console。它打印出類似「25%」的數字,然後打印數字\b,立即擦除打印內容,然後「26%」再次立即擦除,依此類推。

該計劃是解析字符串,TextCtrl.AppendText()一切,但退格字符,然後TextCtrl.Remove()儘可能多的字符,因爲有退格字符。

下面的代碼工作正常,當我用調試器進行調試時,它會在「鬆動」時崩潰。似乎有一些時間/線程問題。顯然我不能在TextCtrl.AppendText()之後撥打TextCtrl.Remove()

class RedirectText: 
    def __init__(self, textCtrl): 
     self.out = textCtrl 

    def write(self, string): 
     new_string = "" 
     number_of_backspaces = 0 
     # this could definitely be improved performance wise... 
     for c in string: 
      if c == "\b": 
       number_of_backspaces += 1 
      else: 
       new_string += c 

     self.out.AppendText(new_string) 
     if number_of_backspaces > 0: 
      last_position = self.out.GetLastPosition() 
      self.out.Remove(last_position - number_of_backspaces, last_position) 

    def flush(self): 
     None 

調用esptool.py的代碼在其自己的線程中運行,以免佔用主UI線程。

這是我第一個真正的Python項目(因此當然是第一個w/wxPython),而且我多年來沒有爲桌面編碼。所以,我完全有可能錯過顯而易見的東西。

+0

剛剛發現'wx.CallAfter',我需要包裝'TextCtrl'操作在我的情況。 –

回答

1

爲了完整起見,這裏有(解決方案之一)。

原來,快速連續使用wx.CallAfter操作文本控件並不太可靠,因此不太可靠。因此,它現在只是附加文本並記住有多少個字符可以刪除下一個時間write()被調用。然後在追加新文本之前刪除這些字符。

class RedirectText: 
    def __init__(self, text_ctrl): 
     self.out = text_ctrl 
     self.pending_backspaces = 0 

    def write(self, string): 
     new_string = "" 
     number_of_backspaces = 0 
     for c in string: 
      if c == "\b": 
       number_of_backspaces += 1 
      else: 
       new_string += c 

     if self.pending_backspaces > 0: 
      # current value minus pending backspaces plus new string 
      new_value = self.out.GetValue()[:-1 * self.pending_backspaces] + new_string 
      wx.CallAfter(self.out.SetValue, new_value) 
     else: 
      wx.CallAfter(self.out.AppendText, new_string) 

     self.pending_backspaces = number_of_backspaces 

    def flush(self): 
     None