⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 intctrl.py

📁 Wxpython Implemented on Windows CE, Source code
💻 PY
📖 第 1 页 / 共 3 页
字号:
#----------------------------------------------------------------------------
# Name:         wxPython.lib.intctrl.py
# Author:       Will Sadkin
# Created:      01/16/2003
# Copyright:   (c) 2003 by Will Sadkin
# RCS-ID:      $Id: intctrl.py,v 1.6 2003/12/22 19:09:52 RD Exp $
# License:     wxWindows license
#----------------------------------------------------------------------------
# NOTE:
#   This was written to provide a standard integer edit control for wxPython.
#
#   IntCtrl permits integer (long) values to be retrieved or  set via
#   .GetValue() and .SetValue(), and provides an EVT_INT() event function
#   for trapping changes to the control.
#
#   It supports negative integers as well as the naturals, and does not
#   permit leading zeros or an empty control; attempting to delete the
#   contents of the control will result in a (selected) value of zero,
#   thus preserving a legitimate integer value, or an empty control
#   (if a value of None is allowed for the control.) Similarly, replacing the
#   contents of the control with '-' will result in a selected (absolute)
#   value of -1.
#
#   IntCtrl also supports range limits, with the option of either
#   enforcing them or simply coloring the text of the control if the limits
#   are exceeded.
#----------------------------------------------------------------------------
# 12/08/2003 - Jeff Grimmett (grimmtooth@softhome.net)
#
# o 2.5 Compatability changes
#
# 12/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
#
# o wxIntUpdateEvent -> IntUpdateEvent
# o wxIntValidator -> IntValidator
# o wxIntCtrl -> IntCtrl 
#

import  string
import  types

import  wx

#----------------------------------------------------------------------------

from sys import maxint
MAXINT = maxint     # (constants should be in upper case)
MININT = -maxint-1

#----------------------------------------------------------------------------

# Used to trap events indicating that the current
# integer value of the control has been changed.
wxEVT_COMMAND_INT_UPDATED = wx.NewEventType()
EVT_INT = wx.PyEventBinder(wxEVT_COMMAND_INT_UPDATED, 1)

#----------------------------------------------------------------------------

# wxWindows' wxTextCtrl translates Composite "control key"
# events into single events before returning them to its OnChar
# routine.  The doc says that this results in 1 for Ctrl-A, 2 for
# Ctrl-B, etc. However, there are no wxPython or wxWindows
# symbols for them, so I'm defining codes for Ctrl-X (cut) and
# Ctrl-V (paste) here for readability:
WXK_CTRL_X = (ord('X')+1) - ord('A')
WXK_CTRL_V = (ord('V')+1) - ord('A')

class IntUpdatedEvent(wx.PyCommandEvent):
    def __init__(self, id, value = 0, object=None):
        wx.PyCommandEvent.__init__(self, wxEVT_COMMAND_INT_UPDATED, id)

        self.__value = value
        self.SetEventObject(object)

    def GetValue(self):
        """Retrieve the value of the control at the time
        this event was generated."""
        return self.__value


#----------------------------------------------------------------------------

class IntValidator( wx.PyValidator ):
    """
    Validator class used with IntCtrl; handles all validation of input
    prior to changing the value of the underlying wx.TextCtrl.
    """
    def __init__(self):
        wx.PyValidator.__init__(self)
        self.Bind(wx.EVT_CHAR, self.OnChar)

    def Clone (self):
        return self.__class__()

    def Validate(self, window):     # window here is the *parent* of the ctrl
        """
        Because each operation on the control is vetted as it's made,
        the value of the control is always valid.
        """
        return 1


    def OnChar(self, event):
        """
        Validates keystrokes to make sure the resulting value will a legal
        value.  Erasing the value causes it to be set to 0, with the value
        selected, so it can be replaced.  Similarly, replacing the value
        with a '-' sign causes the value to become -1, with the value
        selected.  Leading zeros are removed if introduced by selection,
        and are prevented from being inserted.
        """
        key = event.KeyCode()
        ctrl = event.GetEventObject()


        value = ctrl.GetValue()
        textval = wx.TextCtrl.GetValue(ctrl)
        allow_none = ctrl.IsNoneAllowed()

        pos = ctrl.GetInsertionPoint()
        sel_start, sel_to = ctrl.GetSelection()
        select_len = sel_to - sel_start

# (Uncomment for debugging:)
##        print 'keycode:', key
##        print 'pos:', pos
##        print 'sel_start, sel_to:', sel_start, sel_to
##        print 'select_len:', select_len
##        print 'textval:', textval

        # set defaults for processing:
        allow_event = 1
        set_to_none = 0
        set_to_zero = 0
        set_to_minus_one = 0
        paste = 0
        internally_set = 0

        new_value = value
        new_text = textval
        new_pos = pos

        # Validate action, and predict resulting value, so we can
        # range check the result and validate that too.

        if key in (wx.WXK_DELETE, wx.WXK_BACK, WXK_CTRL_X):
            if select_len:
                new_text = textval[:sel_start] + textval[sel_to:]
            elif key == wx.WXK_DELETE and pos < len(textval):
                new_text = textval[:pos] + textval[pos+1:]
            elif key == wx.WXK_BACK and pos > 0:
                new_text = textval[:pos-1] + textval[pos:]
            # (else value shouldn't change)

            if new_text in ('', '-'):
                # Deletion of last significant digit:
                if allow_none and new_text == '':
                    new_value = None
                    set_to_none = 1
                else:
                    new_value = 0
                    set_to_zero = 1
            else:
                try:
                    new_value = ctrl._fromGUI(new_text)
                except ValueError:
                    allow_event = 0


        elif key == WXK_CTRL_V:   # (see comments at top of file)
            # Only allow paste if number:
            paste_text = ctrl._getClipboardContents()
            new_text = textval[:sel_start] + paste_text + textval[sel_to:]
            if new_text == '' and allow_none:
                new_value = None
                set_to_none = 1
            else:
                try:
                    # Convert the resulting strings, verifying they
                    # are legal integers and will fit in proper
                    # size if ctrl limited to int. (if not,
                    # disallow event.)
                    new_value = ctrl._fromGUI(new_text)

                    if paste_text:
                        paste_value = ctrl._fromGUI(paste_text)
                    else:
                        paste_value = 0

                    new_pos = sel_start + len(str(paste_value))

                    # if resulting value is 0, truncate and highlight value:
                    if new_value == 0 and len(new_text) > 1:
                        set_to_zero = 1

                    elif paste_value == 0:
                        # Disallow pasting a leading zero with nothing selected:
                        if( select_len == 0
                            and value is not None
                            and ( (value >= 0 and pos == 0)
                                  or (value < 0 and pos in [0,1]) ) ):
                            allow_event = 0

                    paste = 1

                except ValueError:
                    allow_event = 0


        elif key < wx.WXK_SPACE or key > 255:
            pass    # event ok


        elif chr(key) == '-':
            # Allow '-' to result in -1 if replacing entire contents:
            if( value is None
                or (value == 0 and pos == 0)
                or (select_len >= len(str(abs(value)))) ):
                new_value = -1
                set_to_minus_one = 1

            # else allow negative sign only at start, and only if
            # number isn't already zero or negative:
            elif pos != 0 or (value is not None and value < 0):
                allow_event = 0
            else:
                new_text = '-' + textval
                new_pos = 1
                try:
                    new_value = ctrl._fromGUI(new_text)
                except ValueError:
                    allow_event = 0


        elif chr(key) in string.digits:
            # disallow inserting a leading zero with nothing selected
            if( chr(key) == '0'
                and select_len == 0
                and value is not None
                and ( (value >= 0 and pos == 0)
                      or (value < 0 and pos in [0,1]) ) ):
                allow_event = 0
            # disallow inserting digits before the minus sign:
            elif value is not None and value < 0 and pos == 0:
                allow_event = 0
            else:
                new_text = textval[:sel_start] + chr(key) + textval[sel_to:]
                try:
                    new_value = ctrl._fromGUI(new_text)
                except ValueError:
                    allow_event = 0

        else:
            # not a legal char
            allow_event = 0


        if allow_event:
            # Do range checking for new candidate value:
            if ctrl.IsLimited() and not ctrl.IsInBounds(new_value):
                allow_event = 0
            elif new_value is not None:
                # ensure resulting text doesn't result in a leading 0:
                if not set_to_zero and not set_to_minus_one:
                    if( (new_value > 0 and new_text[0] == '0')
                        or (new_value < 0 and new_text[1] == '0')
                        or (new_value == 0 and select_len > 1 ) ):

                        # Allow replacement of leading chars with
                        # zero, but remove the leading zero, effectively
                        # making this like "remove leading digits"

                        # Account for leading zero when positioning cursor:
                        if( key == wx.WXK_BACK
                            or (paste and paste_value == 0 and new_pos > 0) ):
                            new_pos = new_pos - 1

                        wx.CallAfter(ctrl.SetValue, new_value)
                        wx.CallAfter(ctrl.SetInsertionPoint, new_pos)
                        internally_set = 1

                    elif paste:
                        # Always do paste numerically, to remove
                        # leading/trailing spaces
                        wx.CallAfter(ctrl.SetValue, new_value)
                        wx.CallAfter(ctrl.SetInsertionPoint, new_pos)
                        internally_set = 1

                    elif (new_value == 0 and len(new_text) > 1 ):
                        allow_event = 0

                if allow_event:
                    ctrl._colorValue(new_value)   # (one way or t'other)

# (Uncomment for debugging:)
##        if allow_event:
##            print 'new value:', new_value
##            if paste: print 'paste'
##            if set_to_none: print 'set_to_none'
##            if set_to_zero: print 'set_to_zero'
##            if set_to_minus_one: print 'set_to_minus_one'
##            if internally_set: print 'internally_set'
##        else:
##            print 'new text:', new_text

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -