2

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()
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
devtk
  • 1,999
  • 2
  • 18
  • 24

0 Answers0