如何持续更新(terminallike)wxPython TextC

2024-09-22 20:24:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在为esptool.py开发wxpythongui,即应用程序将调用该脚本。首先,我想重定向内容esptool.py打印到控制台到文本控制。我遵循了一个frequently referenced article的方法,效果很好。在

但是,我目前正忙于处理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),而且我已经很多年没有为桌面编写代码了。所以,我完全有可能遗漏了一些显而易见的东西。在


Tags: of代码pyselfnumber内容stringout
1条回答
网友
1楼 · 发布于 2024-09-22 20:24:10

为了完整起见,这里有一个解决方案。在

结果表明,连续使用wx.CallAfter操作文本控件并不太可靠。因此,它现在只追加文本并记住调用了多少个字符来删除nexttimewrite()。然后在附加新文本之前删除这些字符。在

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

相关问题 更多 >