Hide Caret in wxTextCtrl

1,235 views
Skip to first unread message

evstevemd

unread,
Sep 27, 2009, 8:55:48 PM9/27/09
to wxPython-users
Hi All,
How do I hide caret (i.e ---> | ) from wxTextCtrl.
I want still to be able to select text, copy and paste. I have
searched and met people with the problem but their quest went
unanswered!
Thanks

--Steve --

Robin Dunn

unread,
Sep 28, 2009, 2:39:45 PM9/28/09
to wxpytho...@googlegroups.com

You may be able to do it by calling HideCaret via ctypes, but I did find
one message stating that that API doesn't apply to the standard text
control because it handles the caret in a different way. (It probably
draws it itself.)

Why are you wanting to do this? Perhaps a different widget, or a custom
one, will meet your needs better.

--
Robin Dunn
Software Craftsman
http://wxPython.org

evstevemd

unread,
Sep 28, 2009, 4:55:40 PM9/28/09
to wxPython-users
Hi Robin and all,


> Why are you wanting to do this?  Perhaps a different widget, or a custom
> one, will meet your needs better.

I want to display text where user doesn't edit. He can only select/
copy (sorry for my typo above, no paste)
> --
> Robin Dunn
> Software Craftsmanhttp://wxPython.org

Mike Conley

unread,
Sep 28, 2009, 5:05:34 PM9/28/09
to wxpytho...@googlegroups.com
If you want to dig a little, look at the output window control used in the SPE editor. It seems to have the desired behavior.



Robin Dunn

unread,
Sep 28, 2009, 5:19:01 PM9/28/09
to wxpytho...@googlegroups.com
On 9/28/09 1:55 PM, evstevemd wrote:
>
> Hi Robin and all,
>
>
>> Why are you wanting to do this? Perhaps a different widget, or a custom
>> one, will meet your needs better.
>
> I want to display text where user doesn't edit. He can only select/
> copy (sorry for my typo above, no paste)

Have you tried using the wx.TE_READ_ONLY style? It probably still
displays the caret since it allows you to select text by the keyboard
and to position the caret to be able to do so, but otherwise it gives
you what you want.

XXchaosXX

unread,
Oct 8, 2009, 11:02:03 AM10/8/09
to wxPython-users
yourTextCtrl.GetCaret().Hide()

hope that helps

Mike Conley

unread,
Oct 8, 2009, 12:59:02 PM10/8/09
to wxpytho...@googlegroups.com

On Thu, Oct 8, 2009 at 11:02 AM, XXchaosXX <both...@googlemail.com> wrote:

yourTextCtrl.GetCaret().Hide()

hope that helps


Doesn't seem to work even though it looks like it should according to the documentation. This simple test fails. I tried GetCaret() after Show() also, and it still returned None.


import wx

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)

        panel = wx.Panel(self, -1)
        tc1 = wx.TextCtrl(panel, -1, "text control 1")
        tc2 = wx.TextCtrl(panel, -1, "text control 2")

        caret = tc2.GetCaret()   # this returns None
        caret.Hide()             # so this fails

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(tc1, 1, wx.ALL|wx.EXPAND, 10)
        sizer.Add(tc2, 1, wx.ALL|wx.EXPAND, 10)
        panel.SetSizer(sizer)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(panel, 1, wx.EXPAND, 0)
        self.SetSizer(sizer)
        sizer.Fit(self)
        self.Layout()

app = wx.PySimpleApp(0)
frame = MyFrame(None)
frame.Show()
app.MainLoop()
 

Robin Dunn

unread,
Oct 8, 2009, 3:04:01 PM10/8/09
to wxpytho...@googlegroups.com
On 10/8/09 9:59 AM, Mike Conley wrote:
>
> On Thu, Oct 8, 2009 at 11:02 AM, XXchaosXX <both...@googlemail.com
> <mailto:both...@googlemail.com>> wrote:
>
>
> yourTextCtrl.GetCaret().Hide()
>
> hope that helps
>
>
> Doesn't seem to work even though it looks like it should according to
> the documentation. This simple test fails. I tried GetCaret() after
> Show() also, and it still returned None.

The Caret referred to by GetCaret is a wx.Caret which is intended for
use with your own custom classes that need a caret not the native
widgets. Unless you explicitly created one of them then the window
doesn't have a wx.Caret.

The caret you see in a wx.TextCtrl is one provided by the native control
and wx doesn't have access to it. If the native widget allows you to
turn it on or off then it may be possible to do it via a native API
accessible with ctypes or something, but wx doesn't expose anything like
that.

Victor Rybynok

unread,
Dec 4, 2009, 12:01:25 PM12/4/09
to wxPython-users
Does anyone know what happened to this ticket: http://trac.wxwidgets.org/ticket/5990
?

There are also two undocomented methods, present in wxPython2.8 (win32-
unicode-2.8.10.1-py26):
wx.TextCtrl.HideNativeCaret(self) -> bool
wx.TextCtrl.ShowNativeCaret(self, bool show=True) -> bool

Those methods suppose to control the cursor natively supplied by the
wxTextCtrl. Calling them has no effect on instances of wxTextCtrl.
HideNativeCaret() returns false.

Victor

On Oct 8, 7:04 pm, Robin Dunn <ro...@alldunn.com> wrote:
> > yourTextCtrl.GetCaret().Hide()

Robin Dunn

unread,
Dec 9, 2009, 3:24:43 PM12/9/09
to wxpytho...@googlegroups.com
On 12/4/09 9:01 AM, Victor Rybynok wrote:
> Does anyone know what happened to this ticket: http://trac.wxwidgets.org/ticket/5990
> ?
>
> There are also two undocomented methods, present in wxPython2.8 (win32-
> unicode-2.8.10.1-py26):
> wx.TextCtrl.HideNativeCaret(self) -> bool
> wx.TextCtrl.ShowNativeCaret(self, bool show=True) -> bool
>
> Those methods suppose to control the cursor natively supplied by the
> wxTextCtrl. Calling them has no effect on instances of wxTextCtrl.
> HideNativeCaret() returns false.

Here's the implementation, it just maps to the native ShowCaret and
HideCaret APIs.


bool wxTextCtrl::ShowNativeCaret(bool show)
{
if ( show != m_isNativeCaretShown )
{
if ( !(show ? ::ShowCaret(GetHwnd()) : ::HideCaret(GetHwnd())) )
{
// not an error, may simply indicate that it's not shown/hidden
// yet (i.e. it had been hidden/showh 2 times before)
return false;
}

m_isNativeCaretShown = show;
}

return true;

Victor Rybynok

unread,
Dec 10, 2009, 11:55:00 AM12/10/09
to wxpytho...@googlegroups.com
Robin, thanks a lot. I have to start looking into source code more often :)

Here is a solution for hiding the native caret in wxTextCtrl under Windows (PyCrust session):
import wx
f = wx.Frame(None)
t = wx.TextCtrl(f)
sz = wx.BoxSizer()
sz.Add(t)
<wx._core.SizerItem; proxy of <Swig Object of type 'wxSizerItem *' at 0x3700f18> >
f.SetSizer(sz)
f.Show()
True
def OnFocus(event):
    t.ShowNativeCaret(False)
    event.Skip()
   
t.Bind(wx.EVT_SET_FOCUS, OnFocus)


What happens is when wxTextCtrl receives focus it shows its caret, when it loses focus it hides its caret. wx.EVT_SET_FOCUS is fired after that default processing and we can hide caret in its handling function (processing routine, handler - how do you call it?).

Now I wonder, how useful is to hide caret ;)

Victor.

Victor Rybynok

unread,
Dec 10, 2009, 12:18:55 PM12/10/09
to wxpytho...@googlegroups.com
Here is one more wxTextCtrl behaviour-related solution.
Working with wx.lib.expando.ExpandoTextCtrl, I found that sometimes it may be useful to force text control to behave like wx.StaticText for mouse events, cursor changes and focusing. Thus, you may have an "expando label".

class ExpandoTextView(ExpandoTextCtrl):
    def __init__(self, parent, id=-1, value="",
            style=wx.TE_READONLY|wx.BORDER_NONE, name=u"BodyText"):
        ExpandoTextCtrl.__init__(self, parent, id, value, wx.DefaultPosition,
            wx.DefaultSize, style, wx.DefaultValidator, name)
        #self.SetBackgroundColour(wx.GREEN)
        self.UseExtraHeight(False)

        self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseEvent)
        self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)

    def OnMouseEvent(self, event):
        if event.Moving():
            self.SetCursor(wx.STANDARD_CURSOR)

    def OnSetFocus(self, event):
        self.Navigate(wx.NavigationKeyEvent.IsForward)


I have only checked it for Windows.

Victor
Reply all
Reply to author
Forward
0 new messages