Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problems with wx.lib.masked.numctrl.NumCtrl #2587

Open
JamesRandom opened this issue Aug 20, 2024 · 1 comment
Open

Problems with wx.lib.masked.numctrl.NumCtrl #2587

JamesRandom opened this issue Aug 20, 2024 · 1 comment

Comments

@JamesRandom
Copy link

Operating system: Mac OS Sonoma 14.6 (23G80) (Apple M1 hardware)
wxPython version & source: wxPython==4.2.1 (pypi)
Python version & source: Python 3.11.9 (main, Apr 3 2024, 23:19:16) [Clang 15.0.0 (clang-1500.1.0.2.5)]
(Mac ports)

Description of the problem:

There are several problems with the masked NumCtrl, which make it unusuable. I have described three below. I have also seen some other errors, but the causes (the sequence of inputs and edits) are not so easy to reproduce.

1. Unable to type if initial digits deleted

If I delete the initial value in the control, I can't type anything. Attempting to type digits results in the following error:

Traceback (most recent call last):
  File "/Users/jamie/Library/Python/3.11/lib/python/site-packages/wx/lib/masked/maskededit.py", line 3088, in _OnChar
    if keep_processing and self._isCharAllowed( char, pos, checkRegex = True ):
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jamie/Library/Python/3.11/lib/python/site-packages/wx/lib/masked/maskededit.py", line 4712, in _isCharAllowed
    and (sel_to == end or (sel_to < self._masklength and value[sel_start] != field._fillChar))
                                                         ~~~~~^^^^^^^^^^^
IndexError: string index out of range

The displayed number is

2. Deleting the decimal point

If I delete the decimal point and then attempt to type "." I get the following error message:

Traceback (most recent call last):
  File "/Users/jamie/Library/Python/3.11/lib/python/site-packages/wx/lib/masked/maskededit.py", line 3049, in _OnChar
    keep_processing = self._keyhandlers[key](event)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jamie/Library/Python/3.11/lib/python/site-packages/wx/lib/masked/maskededit.py", line 3992, in _OnDecimalPoint
    newstr = self._adjustFloat(value)
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jamie/Library/Python/3.11/lib/python/site-packages/wx/lib/masked/maskededit.py", line 4439, in _adjustFloat
    intStr, fracStr = value.split(self._decimalChar)
    ^^^^^^^^^^^^^^^
ValueError: not enough values to unpack (expected 2, got 1)

If I move the cursor and then type a decimal point then the program crashes with:

Python[44871:4565493] *** Assertion failure in -[NSTextRange initWithLocation:endLocation:], NSTextRange.m:32
Fatal Python error: PyGILState_Release: thread state 0x1036eb260 must be current when releasing
Python runtime state: initialized

Current thread 0x00000001f7804f40 (most recent call first):
  File "/Users/jamie/Library/Python/3.11/lib/python/site-packages/wx/lib/masked/textctrl.py", line 140 in _SetSelection
  File "/Users/jamie/Library/Python/3.11/lib/python/site-packages/wx/core.py", line 3427 in <lambda>
  File "/Users/jamie/Library/Python/3.11/lib/python/site-packages/wx/core.py", line 2262 in MainLoop
  File "/Users/jamie/Documents/Projects/python/timer/src/test.py", line 37 in main
  File "/Users/jamie/Documents/Projects/python/timer/src/test.py", line 41 in <module>

Extension modules: wx._core (total: 1)
Abort trap: 6

3. Errors after deleting leading spaces

The initial value in the control is preceded by several (10) spaces. Deleting more than 4 of these results in the following error:

Traceback (most recent call last):
  File "/Users/jamie/Library/Python/3.11/lib/python/site-packages/wx/lib/masked/numctrl.py", line 1258, in OnTextChange
    if not BaseMaskedTextCtrl._OnTextChange(self, event):
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jamie/Library/Python/3.11/lib/python/site-packages/wx/lib/masked/maskededit.py", line 2965, in _OnTextChange
    self._CheckValid()  # Recolor control as appropriate
    ^^^^^^^^^^^^^^^^^^
  File "/Users/jamie/Library/Python/3.11/lib/python/site-packages/wx/lib/masked/maskededit.py", line 5377, in _CheckValid
    self._applyFormatting()
  File "/Users/jamie/Library/Python/3.11/lib/python/site-packages/wx/lib/masked/maskededit.py", line 4784, in _applyFormatting
    text, signpos, right_signpos = self._getSignedValue()
                                   ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jamie/Library/Python/3.11/lib/python/site-packages/wx/lib/masked/maskededit.py", line 4955, in _getSignedValue
    abstext, signpos, right_signpos = self._getAbsValue(text)
                                      ^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jamie/Library/Python/3.11/lib/python/site-packages/wx/lib/masked/maskededit.py", line 4919, in _getAbsValue
    if len(text) >= signpos+1 and  text[signpos+1] in ('-','('):
                                   ~~~~^^^^^^^^^^^
IndexError: string index out of range
Traceback (most recent call last):
  File "/Users/jamie/Library/Python/3.11/lib/python/site-packages/wx/lib/masked/maskededit.py", line 5578, in _OnKillFocus
    self._AdjustField(self._GetInsertionPoint())
  File "/Users/jamie/Library/Python/3.11/lib/python/site-packages/wx/lib/masked/maskededit.py", line 4304, in _AdjustField
    newfield = field._AdjustField(slice)
               ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jamie/Library/Python/3.11/lib/python/site-packages/wx/lib/masked/maskededit.py", line 1653, in _AdjustField
    intStr = str(int(intStr))
                 ^^^^^^^^^^^
ValueError: invalid literal for int() with base 10: '0.0'

(That last line is puzzling)

Code Example (click to expand)
#!/usr/bin/env python3

import wx
import wx.lib.masked

class MainWindow(wx.Dialog):
    """Subclass of wx.Frame to serve as the main window of the example"""

    def __init__(self):
        """Create the main window"""

        super().__init__(None, title="Test")

        sizer = wx.BoxSizer(wx.VERTICAL)

        control = wx.lib.masked.numctrl.NumCtrl(parent=self)
        control.SetFractionWidth(2)

        sizer.Add(control, flag=wx.ALIGN_LEFT | wx.EXPAND)

        self.SetSizer(sizer)

def main():

    # Create the Wx App
    app = wx.App()
    # Create the main window with access to the database
    frame = MainWindow()
    app.SetTopWindow(frame)
    frame.Show()
    app.MainLoop()

if __name__ == "__main__":
    main()
@JamesRandom
Copy link
Author

BTW I am currently experimenting with using validators on a text control, as that may be a better solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant