Bagaimana cara mengubah input alfabet di wx.TextCtrl menjadi huruf kapital semua?

Saya mencoba menulis validator pertama saya untuk wx.TextCtrl berdasarkan tanggapan ini untuk pertanyaan lain di SO yang seharusnya melakukan hal berikut:

Semua huruf harus dicetak sebagai huruf kapital dan kolom teks hanya boleh berisi huruf kapital dan angka.

Namun, upaya saya gagal dalam dua hal:

  • Saat saya mengubah templat saya (diambil dari respons tertaut) tidak ada yang ditambahkan ke bidang teks.

  • Saya tidak bisa mengubah huruf kecil menjadi huruf kapital.

Inilah upaya saya:

import wx
import string

########################################################################
class CharValidator(wx.PyValidator):
    ''' Validates data as it is entered into the text controls. '''

    #----------------------------------------------------------------------
    def __init__(self, flag):
        wx.PyValidator.__init__(self)
        self.flag = flag
        self.Bind(wx.EVT_CHAR, self.OnChar)

    #----------------------------------------------------------------------
    def Clone(self):
        '''Required Validator method'''
        return CharValidator(self.flag)

    #----------------------------------------------------------------------
    def Validate(self, win):
        return True

    #----------------------------------------------------------------------
    def TransferToWindow(self):
        return True

    #----------------------------------------------------------------------
    def TransferFromWindow(self):
        return True

    #----------------------------------------------------------------------
    def OnChar(self, event):
        keycode = int(event.GetKeyCode())
        if keycode < 256:
            if keycode > 96 & keycode < 123:
                keycode = keycode - 32
            #print keycode
            key = chr(keycode)
            #print key
            return
        event.Skip()

########################################################################
class ValidationDemo(wx.Frame):
    """"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, wx.ID_ANY, 
                          "Text Validation Tutorial")

        panel = wx.Panel(self)
        textOne = wx.TextCtrl(panel, validator=CharValidator('no-alpha'))

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(textOne, 0, wx.ALL, 5)
        panel.SetSizer(sizer)

# Run the program
if __name__ == "__main__":
    app = wx.App(False)
    frame = ValidationDemo()
    frame.Show()
    app.MainLoop()

person Henrik    schedule 08.04.2012    source sumber


Jawaban (2)


Bingkai Demo Anda memiliki beberapa masalah dengan struktur pohon widget wxPython. Ini akan memungkinkan Anda untuk menulis di kontrol teks:

class ValidationDemo(wx.Frame):
    """"""
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, wx.ID_ANY, 
                          "Text Validation Tutorial")

        textOne = wx.TextCtrl(self, validator=CharValidator('no-alpha'))

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(textOne, 1, wx.ALL| wx.EXPAND, 5)
        self.SetSizer(sizer)
        self.Fit()

Di sisi Validator, Anda tidak mengirimkan surat Anda ke kontrol teks setelah dihitung. Yang lebih buruk lagi, Anda selalu kembali dan menghentikan acara tersebut.

Ini berfungsi (saya jelaskan di komentar):

def OnChar(self, event):
    keycode = int(event.GetKeyCode())
    #
    # get the widget where the text entry takes place
    object = self.GetWindow()
    #
    # for upper-case and for numbers, let the event go
    if (58 > keycode > 47) or ( 91 > keycode > 64):
        event.Skip()
    #
    # for lower-case, convert to upper and write it yourself
    elif 123 > keycode > 96:
        keycode = keycode - 32
        key = chr(keycode)
        object.write(key)

Catatan Saya memanggil self.GetWindow() untuk setiap acara char. Dalam kasus Anda, dengan hanya memiliki satu kontrol menggunakan validator, Anda dapat menentukan self.object hanya sekali pada inisialisasi validator.

person joaquin    schedule 08.04.2012
comment
Terimakasih atas tanggapan Anda. Saya akhirnya menyadari bahwa saya tidak memiliki fungsi validator tetapi pengendali acara seperti yang Anda maksudkan juga. Lihat jawaban saya sendiri yang mengimplementasikan ini. - person Henrik; 12.04.2012

Sebenarnya semua kekacauan dengan fungsi validasi tidak diperlukan. Anda hanya memerlukan eventhandler (perhatikan bahwa penulisannya tidak rapi dan dikodekan dengan keras ke objek textOne tertentu alih-alih mengambil objek input).

Lebih jauh lagi, sepertinya ada baiknya untuk memindahkan InsertionPoint:

import wx

class ValidationDemo(wx.Frame):
    """"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, wx.ID_ANY, 
                          "Text Validation Tutorial")

        panel = wx.Panel(self)
        self.textOne = wx.TextCtrl(panel)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.textOne, 0, wx.ALL, 5)
        panel.SetSizer(sizer)

        self.Bind(wx.EVT_TEXT, self.OnTextType, self.textOne)

    def OnTextType(self, event):
        self.textOne.ChangeValue(unicode.upper(self.textOne.GetValue()))
        self.textOne.SetInsertionPointEnd()


# Run the program
if __name__ == "__main__":
    app = wx.App(False)
    frame = ValidationDemo()
    frame.Show()
    app.MainLoop()
person Henrik    schedule 12.04.2012
comment
Anda harus memilih jawaban yang menjawab pertanyaan dan persyaratan yang Anda posting, bukan renungan Anda sendiri. Bagaimanapun, jawaban Anda tidak memenuhi persyaratan yang Anda posting: pertama, jawaban tersebut tidak memvalidasi apa pun, hanya mengonversi menjadi huruf besar apa pun yang dapat dikonversi, dan kedua, jawaban tersebut tidak sesuai dengan baris yang Anda soroti, bidang teks hanya boleh berisi huruf kapital dan angka . Jadi saya sarankan Anda melakukan downvote otomatis sendiri :-). - person joaquin; 12.04.2012
comment
Mungkin pertanyaan saya salah diartikan. Saya sebenarnya tidak membutuhkan validator. Saya hanya ingin semua huruf menggunakan huruf kapital. Dan Anda benar, pembuangan non digit atau karakter tidak diterapkan. Namun, inilah yang ingin saya capai. Setidaknya ini menjawab pertanyaan literal (yaitu, judul). Saya tidak ingin bersikap kasar dan sangat menghargai jawaban Anda. Tapi inilah jawaban yang saya temukan dan saya posting dan menerimanya sebagai referensi (dan tidak mendapatkan poin apa pun untuk itu). Oke untukmu? - person Henrik; 12.04.2012