Wx.stc.StyledTextCtrl ScrollBar

348 views Asked by At

In my project, I use wx.stc.StyledTextCtrl(). I bind the events of key down and key up. When I want to add a letter into the TextCtrl, I don’t skip the event, in some reasons, I use the method AddText() in order to add a text. When the text is long and the ScrollBar (of the width of the screen) is opened I want that ScrollBar will be at the position where I can see the letter that is added (will move automatically as it should be). currently the ScrollBar always stays at the left side of the screen. I'm searching for a function that can do that.

when the letters are over the width of the TextCtrl (over pos 300) the ScrollBar is still doesn't move. I want that it will be like the messageTxt in the right side of the frame. Here is a basic code that present my problem:

import wx
import wx.stc

def on_key_down(event):
    pass
def on_key_up(event):
    key_code = event.GetKeyCode()
    messageTxt.AddText(chr(key_code))

app = wx.App()
frame = wx.Frame(None, -1, title='2', pos=(0, 0), size=(500, 500))
frame.Show(True)
messageTxt = wx.stc.StyledTextCtrl(frame, id=wx.ID_ANY, pos=(0, 0), size=(300, 300),
                                     style=wx.TE_MULTILINE, name="File")
messageTxt.Bind(wx.EVT_KEY_DOWN, on_key_down)
messageTxt.Bind(wx.EVT_KEY_UP, on_key_up)
messageTxt2 = wx.stc.StyledTextCtrl(frame, id=wx.ID_ANY, pos=(320, 0), size=(150, 150),
                                   style=wx.TE_MULTILINE, name="File")

app.SetTopWindow(frame)
app.MainLoop()

2

There are 2 answers

0
Rolf of Saxony On BEST ANSWER

I've added a different answer because the first issue is still valid, just not for your question, as I interpret it.
I assume this is a mock-up of your problem, if it isn't, let me know and I'll delete it.
The "server updates" are simulated by a timer, the character is added, then we simply move the cursor 1 character to the right.

import wx
import wx.stc

server_sends=['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','T','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','T']

class MyFrame(wx.Frame):
    def __init__(self, parent, id=wx.ID_ANY, title=""):
        super(MyFrame, self).__init__(parent, id, title)
        self.SetSize((500,500))
        self.panel = wx.Panel(self, -1 , size=(500,500))
        self.messageTxt = wx.stc.StyledTextCtrl(self.panel, id=wx.ID_ANY, pos=(0, 0), size=(300, 300),
                                     style=wx.TE_MULTILINE, name="File")
        self.messageTxt2 = wx.stc.StyledTextCtrl(self.panel, id=wx.ID_ANY, pos=(320, 0), size=(150, 150),                                   style=wx.TE_MULTILINE, name="File")
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
        self.timer.Start(500)
        self.cnt = 0
        self.Show()

    def OnTimer(self, event):
        print (server_sends[self.cnt])
        self.Server_Update(server_sends[self.cnt])
        self.cnt += 1
        if self.cnt > len(server_sends) - 1 :
            self.timer.Stop()

    def Server_Update(self,char):
        self.messageTxt.AddText(char)
        self.messageTxt.CharRight()

if __name__ == "__main__":
    app = wx.App()
    frame = MyFrame(None,title="The Main Frame")
    app.MainLoop()

enter image description here

4
Rolf of Saxony On

Clearly another event is ocurring after the key event, which is being missed.
Use event.Skip() in the functions bound to a key event.

Skip(self, skip=True) This method can be used inside an event handler to control whether further event handlers bound to this event will be called after the current one returns.

Without Skip (or equivalently if Skip(false) is used), the event will not be processed any more. If Skip(true) is called, the event processing system continues searching for a further handler function for this event, even though it has been processed already in the current handler.

In general, it is recommended to skip all non-command events to allow the default handling to take place. The command events are, however, normally not skipped as usually a single command such as a button click or menu item selection must only be processed by one handler.

import wx
import wx.stc

def on_key_down(event):
    event.Skip()
    pass
def on_key_up(event):
    key_code = event.GetKeyCode()
    messageTxt.AddText(chr(key_code))
    event.Skip()

app = wx.App()
frame = wx.Frame(None, -1, title='2', pos=(0, 0), size=(500, 500))
frame.Show(True)
messageTxt = wx.stc.StyledTextCtrl(frame, id=wx.ID_ANY, pos=(0, 0), size=(300, 300),
                                     style=wx.TE_MULTILINE, name="File")
messageTxt.Bind(wx.EVT_KEY_DOWN, on_key_down)
messageTxt.Bind(wx.EVT_KEY_UP, on_key_up)
messageTxt2 = wx.stc.StyledTextCtrl(frame, id=wx.ID_ANY, pos=(320, 0), size=(150, 150),
                                   style=wx.TE_MULTILINE, name="File")

app.SetTopWindow(frame)
app.MainLoop()