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

📄 timectrl.py

📁 Wxpython Implemented on Windows CE, Source code
💻 PY
📖 第 1 页 / 共 4 页
字号:
        'limited': False,           # by default, no limiting even if bounds set
        'useFixedWidthFont': True,  # by default, use a fixed-width font
        'oob_color': "Yellow"       # by default, the default masked.TextCtrl "invalid" color
        }

    def __init__ (
                self, parent, id=-1, value = '00:00:00',
                pos = wx.DefaultPosition, size = wx.DefaultSize,
                fmt24hr=False,
                spinButton = None,
                style = wx.TE_PROCESS_TAB,
                validator = wx.DefaultValidator,
                name = "time",
                **kwargs ):

        # set defaults for control:
##        dbg('setting defaults:')

        self.__fmt24hr = False
        wxdt = wx.DateTimeFromDMY(1, 0, 1970)
        try:
            if wxdt.Format('%p') != 'AM':
                TimeCtrl.valid_ctrl_params['format'] = '24HHMMSS'
                self.__fmt24hr = True
                fmt24hr = True  # force/change default positional argument
                                # (will countermand explicit set to False too.)
        except:
            TimeCtrl.valid_ctrl_params['format'] = '24HHMMSS'
            self.__fmt24hr = True
            fmt24hr = True  # force/change default positional argument
                            # (will countermand explicit set to False too.)

        for key, param_value in TimeCtrl.valid_ctrl_params.items():
            # This is done this way to make setattr behave consistently with
            # "private attribute" name mangling
            setattr(self, "_TimeCtrl__" + key, copy.copy(param_value))

        # create locals from current defaults, so we can override if
        # specified in kwargs, and handle uniformly:
        min = self.__min
        max = self.__max
        limited = self.__limited
        self.__posCurrent = 0
        # handle deprecated keword argument name:
        if kwargs.has_key('display_seconds'):
            kwargs['displaySeconds'] = kwargs['display_seconds']
            del kwargs['display_seconds']
        if not kwargs.has_key('displaySeconds'):
            kwargs['displaySeconds'] = True

        # (handle positional arg (from original release) differently from rest of kwargs:)
        if not kwargs.has_key('format'):
            if fmt24hr:
                if kwargs.has_key('displaySeconds') and kwargs['displaySeconds']:
                    kwargs['format'] = '24HHMMSS'
                    del kwargs['displaySeconds']
                else:
                    kwargs['format'] = '24HHMM'
            else:
                if kwargs.has_key('displaySeconds') and kwargs['displaySeconds']:
                    kwargs['format'] = 'HHMMSS'
                    del kwargs['displaySeconds']
                else:
                    kwargs['format'] = 'HHMM'

        if not kwargs.has_key('useFixedWidthFont'):
            # allow control over font selection:
            kwargs['useFixedWidthFont'] = self.__useFixedWidthFont

        maskededit_kwargs = self.SetParameters(**kwargs)

        # allow for explicit size specification:
        if size != wx.DefaultSize:
            # override (and remove) "autofit" autoformat code in standard time formats:
            maskededit_kwargs['formatcodes'] = 'T!'

        # This allows range validation if set
        maskededit_kwargs['validFunc'] = self.IsInBounds

        # This allows range limits to affect insertion into control or not
        # dynamically without affecting individual field constraint validation
        maskededit_kwargs['retainFieldValidation'] = True

        # Now we can initialize the base control:
        BaseMaskedTextCtrl.__init__(
                self, parent, id=id,
                pos=pos, size=size,
                style = style,
                validator = validator,
                name = name,
                setupEventHandling = False,
                **maskededit_kwargs)


        # This makes ':' act like tab (after we fix each ':' key event to remove "shift")
        self._SetKeyHandler(':', self._OnChangeField)


        # This makes the up/down keys act like spin button controls:
        self._SetKeycodeHandler(wx.WXK_UP, self.__OnSpinUp)
        self._SetKeycodeHandler(wx.WXK_DOWN, self.__OnSpinDown)


        # This allows ! and c/C to set the control to the current time:
        self._SetKeyHandler('!', self.__OnSetToNow)
        self._SetKeyHandler('c', self.__OnSetToNow)
        self._SetKeyHandler('C', self.__OnSetToNow)


        # Set up event handling ourselves, so we can insert special
        # processing on the ":' key to remove the "shift" attribute
        # *before* the default handlers have been installed, so
        # that : takes you forward, not back, and so we can issue
        # EVT_TIMEUPDATE events on changes:

        self.Bind(wx.EVT_SET_FOCUS, self._OnFocus )         ## defeat automatic full selection
        self.Bind(wx.EVT_KILL_FOCUS, self._OnKillFocus )    ## run internal validator
        self.Bind(wx.EVT_LEFT_UP, self.__LimitSelection)    ## limit selections to single field
        self.Bind(wx.EVT_LEFT_DCLICK, self._OnDoubleClick ) ## select field under cursor on dclick
        self.Bind(wx.EVT_KEY_DOWN, self._OnKeyDown )        ## capture control events not normally seen, eg ctrl-tab.
        self.Bind(wx.EVT_CHAR, self.__OnChar )              ## remove "shift" attribute from colon key event,
                                                            ## then call BaseMaskedTextCtrl._OnChar with
                                                            ## the possibly modified event.
        self.Bind(wx.EVT_TEXT, self.__OnTextChange, self )  ## color control appropriately and EVT_TIMEUPDATE events


        # Validate initial value and set if appropriate
        try:
            self.SetBounds(min, max)
            self.SetLimited(limited)
            self.SetValue(value)
        except:
            self.SetValue('00:00:00')

        if spinButton:
            self.BindSpinButton(spinButton)     # bind spin button up/down events to this control


    def SetParameters(self, **kwargs):
        """
        Function providing access to the parameters governing TimeCtrl display and bounds.
        """
##        dbg('TimeCtrl::SetParameters(%s)' % repr(kwargs), indent=1)
        maskededit_kwargs = {}
        reset_format = False

        if kwargs.has_key('display_seconds'):
            kwargs['displaySeconds'] = kwargs['display_seconds']
            del kwargs['display_seconds']
        if kwargs.has_key('format') and kwargs.has_key('displaySeconds'):
            del kwargs['displaySeconds']    # always apply format if specified

        # assign keyword args as appropriate:
        for key, param_value in kwargs.items():
            if key not in TimeCtrl.valid_ctrl_params.keys():
                raise AttributeError('invalid keyword argument "%s"' % key)

            if key == 'format':
                wxdt = wx.DateTimeFromDMY(1, 0, 1970)
                try:
                    if wxdt.Format('%p') != 'AM':
                        require24hr = True
                    else:
                        require24hr = False
                except:
                    require24hr = True

                # handle both local or generic 'maskededit' autoformat codes:
                if param_value == 'HHMMSS' or param_value == 'TIMEHHMMSS':
                    self.__displaySeconds = True
                    self.__fmt24hr = False
                elif param_value == 'HHMM' or param_value == 'TIMEHHMM':
                    self.__displaySeconds = False
                    self.__fmt24hr = False
                elif param_value == '24HHMMSS' or param_value == '24HRTIMEHHMMSS':
                    self.__displaySeconds = True
                    self.__fmt24hr = True
                elif param_value == '24HHMM' or param_value == '24HRTIMEHHMM':
                    self.__displaySeconds = False
                    self.__fmt24hr = True
                else:
                    raise AttributeError('"%s" is not a valid format' % param_value)

                if require24hr and not self.__fmt24hr:
                    raise AttributeError('"%s" is an unsupported time format for the current locale' % param_value)

                reset_format = True

            elif key in ("displaySeconds",  "display_seconds") and not kwargs.has_key('format'):
                self.__displaySeconds = param_value
                reset_format = True

            elif key == "min":      min = param_value
            elif key == "max":      max = param_value
            elif key == "limited":  limited = param_value

            elif key == "useFixedWidthFont":
                maskededit_kwargs[key] = param_value

            elif key == "oob_color":
                maskededit_kwargs['invalidBackgroundColor'] = param_value

        if reset_format:
            if self.__fmt24hr:
                if self.__displaySeconds:  maskededit_kwargs['autoformat'] = '24HRTIMEHHMMSS'
                else:                      maskededit_kwargs['autoformat'] = '24HRTIMEHHMM'

                # Set hour field to zero-pad, right-insert, require explicit field change,
                # select entire field on entry, and require a resultant valid entry
                # to allow character entry:
                hourfield = Field(formatcodes='0r<SV', validRegex='0\d|1\d|2[0123]', validRequired=True)
            else:
                if self.__displaySeconds:  maskededit_kwargs['autoformat'] = 'TIMEHHMMSS'
                else:                      maskededit_kwargs['autoformat'] = 'TIMEHHMM'

                # Set hour field to allow spaces (at start), right-insert,
                # require explicit field change, select entire field on entry,
                # and require a resultant valid entry to allow character entry:
                hourfield = Field(formatcodes='_0<rSV', validRegex='0[1-9]| [1-9]|1[012]', validRequired=True)
                ampmfield = Field(formatcodes='S', emptyInvalid = True, validRequired = True)

            # Field 1 is always a zero-padded right-insert minute field,
            # similarly configured as above:
            minutefield = Field(formatcodes='0r<SV', validRegex='[0-5]\d', validRequired=True)

            fields = [ hourfield, minutefield ]
            if self.__displaySeconds:
                fields.append(copy.copy(minutefield))    # second field has same constraints as field 1

            if not self.__fmt24hr:
                fields.append(ampmfield)

            # set fields argument:
            maskededit_kwargs['fields'] = fields

            # This allows range validation if set
            maskededit_kwargs['validFunc'] = self.IsInBounds

            # This allows range limits to affect insertion into control or not
            # dynamically without affecting individual field constraint validation
            maskededit_kwargs['retainFieldValidation'] = True

        if hasattr(self, 'controlInitialized') and self.controlInitialized:
            self.SetCtrlParameters(**maskededit_kwargs)   # set appropriate parameters

            # Validate initial value and set if appropriate
            try:
                self.SetBounds(min, max)
                self.SetLimited(limited)
                self.SetValue(value)
            except:
                self.SetValue('00:00:00')
##            dbg(indent=0)
            return {}   # no arguments to return
        else:
##            dbg(indent=0)
            return maskededit_kwargs


    def BindSpinButton(self, sb):
        """
        This function binds an externally created spin button to the control, so that
        up/down events from the button automatically change the control.
        """
##        dbg('TimeCtrl::BindSpinButton')
        self.__spinButton = sb
        if self.__spinButton:
            # bind event handlers to spin ctrl
            self.__spinButton.Bind(wx.EVT_SPIN_UP, self.__OnSpinUp, self.__spinButton)
            self.__spinButton.Bind(wx.EVT_SPIN_DOWN, self.__OnSpinDown, self.__spinButton)


    def __repr__(self):
        return "<TimeCtrl: %s>" % self.GetValue()


    def SetValue(self, value):
        """
        Validating SetValue function for time values:
        This function will do dynamic type checking on the value argument,
        and convert wxDateTime, mxDateTime, or 12/24 format time string
        into the appropriate format string for the control.
        """
##        dbg('TimeCtrl::SetValue(%s)' % repr(value), indent=1)
        try:
            strtime = self._toGUI(self.__validateValue(value))
        except:
##            dbg('validation failed', indent=0)
            raise

##        dbg('strtime:', strtime)
        self._SetValue(strtime)
##        dbg(indent=0)

    def GetValue(self,
                 as_wxDateTime = False,
                 as_mxDateTime = False,
                 as_wxTimeSpan = False,
                 as_mxDateTimeDelta = False):
        """
        This function returns the value of the display as a string by default, but
        supports return as a wx.DateTime, mx.DateTime, wx.TimeSpan, or mx.DateTimeDelta,
        if requested. (Evaluated in the order above-- first one wins!)
        """


        if as_wxDateTime or as_mxDateTime or as_wxTimeSpan or as_mxDateTimeDelta:
            value = self.GetWxDateTime()
            if as_wxDateTime:
                pass
            elif as_mxDateTime:
                value = DateTime.DateTime(1970, 1, 1, value.GetHour(), value.GetMinute(), value.GetSecond())
            elif as_wxTimeSpan:
                value = wx.TimeSpan(value.GetHour(), value.GetMinute(), value.GetSecond())
            elif as_mxDateTimeDelta:
                value = DateTime.DateTimeDelta(0, value.GetHour(), value.GetMinute(), value.GetSecond())
        else:
            value = BaseMaskedTextCtrl.GetValue(self)
        return value


    def SetWxDateTime(self, wxdt):
        """
        Because SetValue can take a wx.DateTime, this is now just an alias.
        """
        self.SetValue(wxdt)


    def GetWxDateTime(self, value=None):
        """
        This function is the conversion engine for TimeCtrl; it takes
        one of the following types:
            time string
            wxDateTime
            wxTimeSpan
            mxDateTime
            mxDateTimeDelta
        and converts it to a wx.DateTime that always has Jan 1, 1970 as its date
        portion, so that range comparisons around values can work using
        wx.DateTime's built-in comparison function.  If a value is not
        provided to convert, the string value of the control will be used.
        If the value is not one of the accepted types, a ValueError will be
        raised.
        """
        global accept_mx
##        dbg(suspend=1)
##        dbg('TimeCtrl::GetWxDateTime(%s)' % repr(value), indent=1)

⌨️ 快捷键说明

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