如何持续更新(类似终端)一个 wxPython TextCtrl
How to continuously update (terminal-like) a wxPython TextCtrl
我正在为 esptool.py i.e. the app will invoke that script. For starters I'd like to redirect the content that esptool.py prints to console to a TextCtrl. I followed a frequently referenced article 开发 wxPython GUI,它运行良好。
但是,我目前无法处理 progress monitor that esptool.py prints to console。它会打印类似“25%”的内容,然后是一些 \b
,它会立即擦除打印的内容,然后是“26%”,它会再次被立即擦除,依此类推。
计划是解析字符串,TextCtrl.AppendText()
除了退格字符之外的所有内容,然后 TextCtrl.Remove()
有多少退格字符就多少字符。
下面的代码在我用调试器逐步执行时工作正常,但在 "let loose" 时它会严重崩溃。似乎有一些 timing/threading 问题。显然我不能在 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/ w/Python),我已经很多年没有为桌面编写代码了。所以,我完全有可能遗漏了一些明显的东西。
为了完整起见,这里是(其中一个)解决方案。
事实证明,与 GetLastPosition()
相比,使用 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
我正在为 esptool.py i.e. the app will invoke that script. For starters I'd like to redirect the content that esptool.py prints to console to a TextCtrl. I followed a frequently referenced article 开发 wxPython GUI,它运行良好。
但是,我目前无法处理 progress monitor that esptool.py prints to console。它会打印类似“25%”的内容,然后是一些 \b
,它会立即擦除打印的内容,然后是“26%”,它会再次被立即擦除,依此类推。
计划是解析字符串,TextCtrl.AppendText()
除了退格字符之外的所有内容,然后 TextCtrl.Remove()
有多少退格字符就多少字符。
下面的代码在我用调试器逐步执行时工作正常,但在 "let loose" 时它会严重崩溃。似乎有一些 timing/threading 问题。显然我不能在 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/ w/Python),我已经很多年没有为桌面编写代码了。所以,我完全有可能遗漏了一些明显的东西。
为了完整起见,这里是(其中一个)解决方案。
事实证明,与 GetLastPosition()
相比,使用 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