Search code examples
pythonthread-safetywxpythonwx.textctrl

wx.TextCtrl GetLineLength wx.CallAfter not working


I am outputting the stderr to a wx.TextCtrl, after 10 lines I want to delete the first line so there is only ever a maximum of 10 lines in my wx.TextCtrl window. I have a python script which is using multiple threads and classes. I just can't for the life of me get the below bit of code to work, can someone give me a few hints please?

a = 1
while True:
    line = self.process1.stderr.readline().decode('utf-8')
    wx.CallAfter(self.frame.running_log1.AppendText, line)
    if a >= 10:
        s = wx.CallAfter(self.frame.running_log1.GetLineLength, 0) +1
        wx.CallAfter(self.frame.running_log1.Remove, 0, s)
        print s
    a +=1

When run s = None, so fails. I am using wx.CallAfter as I am using threads.


Solution

  • The reason wx.CallAfter returns None is because there isn't anything to return at that point. It can't return the length, because all it has done is made a note that at some point soon it needs to call the function. It hasn't actually called the function, and won't wait until the function has been called.

    In this situation I would write a method that would append a line and remove the first line as necessary. This might look something like:

        def appendAndTrim(self, line):
            self.frame.running_log1.AppendText(line)
            self.line_count += 1
            if self.line_count > 10:
                first_line_length = self.frame.running_log1.GetLineLength(0) + 1
                self.frame.running_log1.Remove(0, first_line_length)
    

    I would then pass this single method to wx.CallAfter, rather than making three separate calls to wx.CallAfter:

    self.line_count = 0
    while True:
        line = self.process1.stderr.readline().decode('utf-8')
        wx.CallAfter(self.appendAndTrim, line)