views:

510

answers:

2

I was looking for a way to transform text entered into the textctrl field to uppercase. I tried using a validator and transforming the value of the key event object to the uppercase letter char value using 'ord' however I could not find any 'set' methods. I may be able to access the event class variable directly as class variables in python are never really private but im having trouble finding the exact information I need to do that.

Anyway this seems like an overly complicated approach. Does anyone else have any suggestions. Am I missing something obvious?

+2  A: 

Try this.

import wx

class UpperTextCtrl(wx.TextCtrl):
    def __init__(self, *args, **kwargs):
        super(UpperTextCtrl, self).__init__(*args, **kwargs)
        self.Bind(wx.EVT_TEXT, self.on_text)
    def on_text(self, event):
        event.Skip()
        selection = self.GetSelection()
        value = self.GetValue().upper()
        self.ChangeValue(value)
        self.SetSelection(*selection)

class Frame(wx.Frame):
    def __init__(self):
        super(Frame, self).__init__(None, -1, 'Uppercase Text Control')
        panel = wx.Panel(self, -1)
        sizer = wx.BoxSizer(wx.VERTICAL)
        text = UpperTextCtrl(panel, -1, style=wx.TE_MULTILINE)

        # change the font
        font = text.GetFont()
        font.SetPointSize(12)
        text.SetFont(font)

        sizer.Add(text, 1, wx.EXPAND|wx.ALL, 10)
        panel.SetSizer(sizer)

if __name__ == '__main__':
    app = wx.PySimpleApp()
    frame = Frame()
    frame.Show()
    app.MainLoop()
FogleBird
Very nice. I considered altering the text selection, but I thought it might be a little slow, it is not. Not noticeable for anyone typing anyway .. Thank you this is very very cool.Actually for my purposes, subclassing the control gives me A LOT more ideas for controlling it, thank you again.
Matt1776
Should use ChangeValue instead of SetValue to avoid a recursion bug. (SetValue generates the EVT_TEXT event again.) I've edited the code. I didn't notice on my iMac but I noticed on Windows.
FogleBird
You know .. I feel like I should be able to figure this one out on my own .. but I cant seem to find the right way. I want to be able to add to this the ability to change its font and keep it that same style, it works fine up until it goes through the ontext upper() routine. Ive tried setting the font after that with some very very weird results. Any ideas? Ive been researching this for some time
Matt1776
You want to change the font on the fly or just once when creating the control?
FogleBird
Just once so anything entered in the box will be styled appropriately. SetDefaultFont wont work .. it works on the numbers and as soon as the text gets run through the upper it goes back to default regular text. Nothing I did worked .. and I am now digging around in the wx base files to see if i can find a copy of the guts of the text ctrl ..
Matt1776
Just use SetFont after creating the control. I usually get the font, tweak it, and then set it again. I'll edit the code in my answer to show an example.
FogleBird
Wow this works .. what was I doing wrong? I think when I wanted to apply a 'style' those are a little more touchy .. but when I look at the style it really isnt that much different then just specifying a larger font size. Thanks for the tip, as always you rule :)
Matt1776
A: 

Hello. This is my solution. What do you think about?

import wx
import string

class UpperTextCtrl(wx.TextCtrl):
    def __init__(self, *args, **kwargs):
        super(UpperTextCtrl, self).__init__(*args, **kwargs)
        self.Bind(wx.EVT_CHAR, self.on_char)
    def on_char(self, event):
        key=event.GetKeyCode()
        text_ctrl=event.GetEventObject()
        if chr(key) in string.letters:
            text_ctrl.AppendText(chr(key).upper())
            return
        event.Skip()

class Frame(wx.Frame):
    def __init__(self):
        super(Frame, self).__init__(None, -1, 'Uppercase Text Control')
        panel = wx.Panel(self, -1)
        sizer = wx.BoxSizer(wx.VERTICAL)
        text = UpperTextCtrl(panel, -1, style=wx.TE_MULTILINE)

        # change the font
        font = text.GetFont()
        font.SetPointSize(12)
        text.SetFont(font)

        sizer.Add(text, 1, wx.EXPAND|wx.ALL, 10)
        panel.SetSizer(sizer)

if __name__ == '__main__':
    app = wx.PySimpleApp()
    frame = Frame()
    frame.Show()
    app.MainLoop()

regards

Antstud