I have a wxTextCtrl element and I want to determine whether it is vertically scrolled to the bottom of the text buffer. It would appear that the functions GetScrollPos
and GetScrollRange
in combination with GetScrollThumb
to get the number of displayed lines would work, but GetScrollThumb
is returning 0
for me no matter what.
How can I determine if the textCtrl is scrolled to the bottom? Is there another method? Is GetScrollThumb
returning 0
a bug or just not supported on my platform?
I'm on windows, using wxPython 4.0.4 msw (phoenix) wxWidgets 3.0.5.
Here is a minimal (non)working example:
#!/usr/bin/python
import wx
print(wx.version())
class TextWindow(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(
self,
parent,
id=wx.ID_ANY,
title=u"Window Title",
pos=wx.DefaultPosition,
size=(400, 200),
style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL,
)
bSizer3 = wx.BoxSizer(wx.VERTICAL)
starting_text = '\n'.join('Line %d' % x for x in range(1, 101))
self.m_textCtrl3 = wx.TextCtrl(
self,
wx.ID_ANY,
starting_text,
wx.DefaultPosition,
wx.DefaultSize,
wx.TE_DONTWRAP | wx.TE_MULTILINE | wx.TE_READONLY,
)
self.m_textCtrl3.SetFont(
wx.Font(
9,
wx.FONTFAMILY_MODERN,
wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_NORMAL,
False,
"Consolas",
)
)
self.m_textCtrl3.HideNativeCaret()
bSizer3.Add(self.m_textCtrl3, 1, wx.ALL | wx.EXPAND, 0)
self.m_staticText1 = wx.StaticText(
self,
wx.ID_ANY,
'',
wx.DefaultPosition,
wx.DefaultSize,
wx.ST_ELLIPSIZE_END,
)
self.m_staticText1.Wrap(-1)
bSizer3.Add(self.m_staticText1, 0, wx.LEFT | wx.EXPAND, 5)
self.SetSizer(bSizer3)
self.Layout()
# Connect Events
self.m_textCtrl3.Bind(wx.EVT_PAINT, self.check_scroll_bar)
def __del__(self):
pass
def check_scroll_bar(self, event):
top_line = self.m_textCtrl3.GetScrollPos(wx.VERTICAL)
line_count = self.m_textCtrl3.GetScrollRange(wx.VERTICAL)
displayed_lines = self.m_textCtrl3.GetScrollThumb(wx.VERTICAL)
scrolled_to_end = top_line + displayed_lines >= line_count
print('%d/%d/%d' % (top_line, displayed_lines, line_count))
self.m_staticText1.SetLabel(
'NOT at the end' if not scrolled_to_end else 'at end')
pass
def main():
app = wx.App()
tw = TextWindow(None)
tw.Show()
app.MainLoop()
if __name__ == "__main__":
main()