How can I delete end-of-line characters in a hidden multiline textctrl

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

How can I delete end-of-line characters in a hidden multiline textctrl

Dennis Carachiola-2
I am attempting to emulate a multiline password field.  I have a textctrl (hidden) in which the plaintext are placed and a second textctrl (shown) in which "*"s are placed.  I have added an EVT_CHAR event handler.  In general, when a char it typed in the shown textctrl, the typed character is WriteText-ed into the hidden textctrl, and an "*" is WriteText-ed into the shown textctrl.  DELETE and BACK are emulated by setting a selection, then Remove-ing the selected chars.  If a DELETE, the selection is set by setting a begin location to the current location and an end location to the current location plus one.  This deletes the next character.  If a BACK, the selection is set by setting the begin location to the current location minus one and the end location to the current location.  This deletes the previous character.  This works fine unless the character to be deleted is a "\n" character representing the end of a line.  Whether the cursor is set at the beginning of a line and BACK is typed, or the cursor is set at the end of a line and DEL is typed.  The results are: the shown line of "*"s is shown correctly, but the hidden line of the actual texts, remains the same, i.e. no "\n"s are deleted.

Below's a slimmed down version of what I have.  when run, typed into the textctrl -------- "*s will be displayed in the box.  If OK is pressed, the textctrl in the hidden textctrl will be typed in the console.  If CANCEL is pressed, the program exits.

I've tried (a) setting a selection and Remove-ing it in the hidden texttrl; (b) WriteText-ing the BACK or DEL into the hidden textctrl; (c) using EmulateKeyPress(event) into the hidden texttrl.  Nothing seems to works.  Any suggestions would be welcome.

import wx

wxapp
= wx.App()    


class TypingDialog (wx.Dialog):

   
def __init__(self):
       
super().__init__(None,
                        id
=wx.ID_ANY,
                        title
="Title")

        main_sizer
= wx.BoxSizer(wx.VERTICAL)

       
self.typed_line = wx.TextCtrl(self,
                                    wx
.ID_ANY,
                                    wx
.EmptyString,
                                    wx
.DefaultPosition,
                                    wx
.DefaultSize,
                                    wx
.TE_MULTILINE | wx.TE_WORDWRAP)
        main_sizer
.Add(self.typed_line, 1, wx.ALL | wx.EXPAND, 5)
       
self.typed_line.Hide()

       
self.hidden_line = wx.TextCtrl(self,
                                    wx
.ID_ANY,
                                   
"hidden",
                                    wx
.DefaultPosition,
                                    wx
.DefaultSize,
                                    wx
.TE_MULTILINE | wx.TE_WORDWRAP)
        main_sizer
.Add(self.hidden_line, 1, wx.ALL | wx.EXPAND, 5)
       
self.hidden_line.Show()
       
self.hidden_line.SetFocus()

        button_sizer
= wx.StdDialogButtonSizer()
       
self.button_sizerOK = wx.Button(self, wx.ID_OK)
        button_sizer
.AddButton(self.button_sizerOK)
       
self.button_sizerCancel = wx.Button(self, wx.ID_CANCEL)
        button_sizer
.AddButton(self.button_sizerCancel)
        button_sizer
.Realize()

        main_sizer
.Add(button_sizer, 0, wx.EXPAND, 5)

       
self.SetSizer(main_sizer)
       
self.Layout()

       
self.Centre(wx.BOTH)

       
self.hidden_line.Bind(wx.EVT_CHAR, self.onTypedText)

       
pass

   
def onTypedText(self, event):
       
UCkeycode = event.GetUnicodeKey()
        keycode
= event.GetKeyCode()
        beg
, end = self.hidden_line.GetSelection()

       
if UCkeycode == wx.WXK_NONE:
           
if keycode == wx.WXK_DELETE:
               
end += 1 if beg == end else 0
               
self.typed_line.Remove(beg, end)
           
event.Skip()

       
elif UCkeycode == wx.WXK_BACK:
            beg
-= 1 if beg == end else 0
           
self.typed_line.Remove(beg, end)
           
event.Skip()

       
elif UCkeycode in [wx.WXK_RETURN]:
           
self.typed_line.SetSelection(beg, end)
           
self.typed_line.WriteText(chr(UCkeycode))
           
self.hidden_line.WriteText(chr(UCkeycode))

       
elif UCkeycode < wx.WXK_SPACE:
           
pass

       
else:
           
self.typed_line.SetSelection(beg, end)
           
self.typed_line.WriteText(chr(UCkeycode))
           
self.hidden_line.WriteText("*")

       
self.hidden_line.SetFocus()


if __name__ == '__main__':

   
with TypingDialog() as td:
        rtn
= ''
       
while rtn is not None:
            rtn
= td.ShowModal()
           
if rtn == wx.ID_CANCEL: break
           
print("\ntyped:\n------\n%s" % td.typed_line.GetValue())
           
print("  OK:", rtn == wx.ID_OK)
           
print()
   
print("\nCancel:", rtn == wx.ID_CANCEL)
   
pass


--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: How can I delete end-of-line characters in a hidden multiline textctrl

Tim Roberts
Dennis Carachiola wrote:

>
> I am attempting to emulate a multiline password field.  I have a
> textctrl (hidden) in which the plaintext are placed and a second
> textctrl (shown) in which "*"s are placed.  I have added an EVT_CHAR
> event handler.  In general, when a char it typed in the shown
> textctrl, the typed character is WriteText-ed into the hidden
> textctrl, and an "*" is WriteText-ed into the shown textctrl.  DELETE
> and BACK are emulated by setting a selection, then Remove-ing the
> selected chars.  If a DELETE, the selection is set by setting a begin
> location to the current location and an end location to the current
> location plus one.  This deletes the next character.  If a BACK, the
> selection is set by setting the begin location to the current location
> minus one and the end location to the current location.  This deletes
> the previous character.  This works fine unless the character to be
> deleted is a "\n" character representing the end of a line.  Whether
> the cursor is set at the beginning of a line and BACK is typed, or the
> cursor is set at the end of a line and DEL is typed.  The results are:
> the shown line of "*"s is shown correctly, but the hidden line of the
> actual texts, remains the same, i.e. no "\n"s are deleted.
I think I have your answer, but you're not going to like it.

Let's say you type "abcd" Enter "efgh" Enter.  If you fetch the text,
you'll get 10 characters: "abcd\nefgh\n", but in the actual control,
there are 12 characters.  Newlines in a text control are stored as
"\r\n".  You can see this if you print self.hidden_line.GetSelection at
the end of onTypeText.  When you hit "Enter", the count increases by two.

You might be better served by skipping the "typed_line" thin altogether,
and just track the text in a simple string.

--
Tim Roberts, [hidden email]
Providenza & Boekelheide, Inc.


--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

smime.p7s (5K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: How can I delete end-of-line characters in a hidden multiline textctrl

Dennis Carachiola-2
In reply to this post by Dennis Carachiola-2
AH HA! Actually, I quite like it.  That's valuable information I didn't have, thank you.  I'll try to adapt my code first, then convert it to saving the text in a string.

Den

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.