1

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()

Rolf of Saxony
  • 21,661
  • 5
  • 39
  • 60
Yuval Sharon
  • 159
  • 8

2 Answers2

2

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()
Rolf of Saxony
  • 21,661
  • 5
  • 39
  • 60
  • In my project, I receive data from a server and I need to add it to the messageTxt using AddText(text). As I said in I don't want to skip the event of key_down. Do you have another solution? – Yuval Sharon Jan 17 '20 at 16:58
  • 1
    I think you may be confusing an English meaning of "skip" i.e. `don't do it` and the wxpython event.Skip() `control whether further event handlers bound to this event will be called after the current one returns` i.e. perform further events like advance the scrollbar. It's a confusing use of the word. Did you try it? – Rolf of Saxony Jan 17 '20 at 18:29
  • I understand what you say. I will explain my self again - In the project, I send each character to the server and if the server allows me to add the character to the messageTxt, I add it using AddText() method. When I use the method AddText() the scrollbar doesn't move by it self. I need a function that can handle it. – Yuval Sharon Jan 17 '20 at 18:58
  • I can only suggest that you provide a better piece of example code, because from what you are saying, the current example does not represent what you are actually doing. – Rolf of Saxony Jan 18 '20 at 10:49
0

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

Rolf of Saxony
  • 21,661
  • 5
  • 39
  • 60