How do I get the scroll position / range from a wx.TextCtrl control in wxPython

喜欢而已 提交于 2019-12-02 07:34:44

问题


I have a little logging app (written in wxPython) that receives data from a bit of kit we're developing, and I want to display the text in a scrolling window. As it stands I'm using a wx.TextCtrl for the text display, but I'm having some issues with the scrolling behaviour.

Basically, I'd like it so that if the scrollbar is at the bottom of the window (i.e. the end of the incoming data), adding more data should scroll the view onwards. If, however the view has been scrolled up a little (i.e. the user is looking at something interesting like an error message), the app should just add the text on the end without scrolling any more.

I've got two problems at the moment:

  1. I can't work out how to retrieve the current scroll position (calls to GetScrollPos() don't seem to work - they just return 0).
  2. I can't work out how to retrieve the current range of the scroll bar (calls to GetScrollRange() just return 1).

I've googled a bit and there seem to be a few hints that suggest GetScrollPos and GetScrollRange won't work for a wx.TextCtrl? Has anyone else had any experience in this area? Is there a nice easy way to solve the problem or am I going to have to roll my own wx.TextCtrl?


回答1:


I just tested a simple example (checking GetScrollPos(0) and GetScrollRange(0) in EVT_TEXT event handler for wx.TextCtrl) and it works fine for me - they return index of currently shown line and total number of lines, respectively.

Maybe the problem is your wxPython version? I used:

>>> import wx
>>> wx.version()
'2.8.9.1 (msw-unicode)'



回答2:


Okay, so here's where I've got to:

import wx
from threading import Timer
import time

class Form1(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)

        self.logger = wx.TextCtrl(self,5, "",wx.Point(20,20), wx.Size(200,200), \
                wx.TE_MULTILINE |  wx.TE_READONLY)# |  wx.TE_RICH2)

        t = Timer(0.1, self.AddText)
        t.start()

    def AddText(self):
        # Resart the timer
        t = Timer(0.25, self.AddText)
        t.start() 

        # Work out if we're at the end of the file
        currentCaretPosition = self.logger.GetInsertionPoint()
        currentLengthOfText = self.logger.GetLastPosition()
        if currentCaretPosition != currentLengthOfText:
            self.holdingBack = True
        else:
            self.holdingBack = False

        timeStamp = str(time.time())

        # If we're not at the end of the file, we're holding back
        if self.holdingBack:
            print "%s FROZEN"%(timeStamp)
            self.logger.Freeze()
            (currentSelectionStart, currentSelectionEnd) = self.logger.GetSelection()
            self.logger.AppendText(timeStamp+"\n")
            self.logger.SetInsertionPoint(currentCaretPosition)
            self.logger.SetSelection(currentSelectionStart, currentSelectionEnd)
            self.logger.Thaw()
        else:
            print "%s THAWED"%(timeStamp)
            self.logger.AppendText(timeStamp+"\n")

app = wx.PySimpleApp()
frame = wx.Frame(None, size=(550,425))
Form1(frame)
frame.Show(1)
app.MainLoop()

This simple demo app works almost perfectly. It scrolls neatly unless the user clicks a line which isn't at the end of the text. Thereafter it stays nice and still so you can select text (note: there's still a bug there in that if you select up not down it clears your selection).

The biggest annoyance is that if I try and enable the "| wx.TE_RICH2" option, it all goes a bit pear-shaped. I really need this to do syntax highlighting of errors, but if I can't enable that option, I'm doomed to monochrome - boo!

Any more ideas on how to hold back scrolling on the rich edit control?



来源:https://stackoverflow.com/questions/153989/how-do-i-get-the-scroll-position-range-from-a-wx-textctrl-control-in-wxpython

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!