1

I have been trying to create an application with npyscreen for a couple weeks now, but I keep running into hangups. I can switch from my main form to a second form. But when I try to switch back to the main form the application does literally nothing. My function gets called, and the self.parentApp.switchForm() function gets called, but doesn't do anything.

The intended functionality is for the main form to allow input for a name. Upon pressing return, the input handler verifies if it is a valid input (checking if it exists in a pre-defined dictionary). If it is, it gathers the value from the dictionary, sets that information in the form that will be displayed next 'SerialForm' then switches to that form. The user then enters the information for the first serial number in that form. If the information matches, it will move on to the next input field. Otherwise it stays on the same input. Once both fields in the 'SerialForm' are entered and match what they should, the program should then log that information and switch back to the 'MAIN' form.

Everything works until I call self.parentApp.switchForm('MAIN') in self.serialTwoInputHandler() debugging makes it to that point but after calling the 'SerialForm' is still there with all the filled in values (Nothing changes at all.) There are no exceptions or errors presented, and I am just at a loss.

NPSAppManaged

class Application(nps.NPSAppManaged):
    def __init__(self, *args, lines=None, columns=None, **kwargs):
        super(Application, self).__init__(*args, **kwargs)

    def onStart(self):
        # self.addFormClass('MAIN', TerminalNameForm, name='EMV Inventory')
        self.addForm('MAIN', TerminalNameForm, name='EMV Inventory')
        self.addForm('SerialForm', SerialNumbersForm, name='')

TerminalNamesForm ('MAIN' Form)

class TerminalNameForm(nps.FormBaseNew):
    def __init__(self, *args, lines=None, columns=None, **kwargs):
        if(not lines or not columns):
            # Get the full terminal size as defualt
            from terminalsize import get_terminal_size
            size = get_terminal_size()
            if (not columns):
                columns = size[0]
            if (not lines):
                lines = size[1]
        super(TerminalNameForm, self).__init__(
            *args, lines=lines, columns=columns, **kwargs)

    def create(self):
        self.promptLabel = self.add(FixedText, value='Enter Terminal Name:')
        self.nameInput = self.add(TitleText, name='> ')
        self.nameInput.setReturnHandler(self.nameInputHandler)

    def nameInputHandler(self, *args, **keywords):
        if(not self.nameInput.value):
            return
        inputName = self.nameInput.value
        global terminalNames
        if(inputName not in terminalNames):
            self.promptLabel.color = 'DANGER'
            self.promptLabel.value = f'Invalid Name: {inputName}'
            self.promptLabel.display()
            return
        sn1 = terminalNames[inputName]['serial1']
        sn2 = terminalNames[inputName]['serial2']

        self.parentApp.getForm('SerialForm').setExpectedValues(inputName, sn1, sn2)
        self.parentApp.switchForm('SerialForm')

    def quit(self):
        self.parentApp.switchForm(None)

SerialNumbersForm ('SerialForm' Form)

class SerialNumbersForm(nps.FormBaseNew):
    #def __init__(self, name, sn1, sn2, *args, lines=None, columns=None, **kwargs):
    def __init__(self, *args, lines=None, columns=None, **kwargs):
        if(not lines or not columns):
            # Get the full terminal size as defualt
            from terminalsize import get_terminal_size
            size = get_terminal_size()
            if (not columns):
                columns = size[0]
            if (not lines):
                lines = size[1]
        self.terminalName = ''
        self.expectedSerialOne = ''
        self.expectedSerialTwo = ''
        super(SerialNumbersForm, self).__init__(*args, lines=lines, columns=columns, **kwargs)

    def create(self):
        self.terminalNameLabel = self.add(FixedText, value=f'Name: {self.terminalName}')
        self.expectedLabel = self.add(FixedText, value='Expected Values:', color='NO_EDIT')
        self.expectedSerialOneLabel = self.add(TitleFixedText, name='\tS/N 1:', value=self.expectedSerialOne)
        self.expectedSerialTwoLabel = self.add(TitleFixedText, name='\tS/N 2:', value=self.expectedSerialTwo)

        newPos = self.expectedSerialTwoLabel.rely+2
        self.serialOneInput = self.add(TitleText, name='S/N 1:', rely=newPos)
        self.serialTwoInput = self.add(TitleText, name='S/N 2:', hidden=True)

        self.add_handlers({'^C': quit})

        self.serialOneInput.setReturnHandler(self.serialOneInputHandler)
        self.serialTwoInput.setReturnHandler(self.serialTwoInputHandler)

    def serialOneInputHandler(self, *args, **keywords):
        if(not self.serialOneInput.value):
            return

        inputValue = self.serialOneInput.value
        if(inputValue == self.expectedSerialOne):
            self.serialOneInput.set_editing(False)
            self.serialTwoInput.set_editing(True)
        else:
            # WHY. WONT. EDITING. COLOR. CHANGE!
            self.serialOneInput.color = 'DANGER'
            self.serialOneInput.labelColor = 'DANGER'

            self.serialOneInput.label_widget.color = 'DANGER'
            self.serialOneInput.label_widget.highlight_color = 'DANGER'

            self.serialOneInput.entry_widget.color = 'DANGER'
            self.serialOneInput.entry_widget.highlight_color = 'DANGER'
            self.serialOneInput.display()
            print()

    def serialTwoInputHandler(self, *args, **keywords):
        if(not self.serialTwoInput.value):
            return

        inputValue = self.serialTwoInput.value
        if(inputValue == self.expectedSerialTwo):
            self.parentApp.setNextForm('MAIN')
            self.parentApp.switchFormNow()

    def setExpectedValues(self, name, sn1, sn2):
        self.terminalName = name
        self.terminalNameLabel.value = f'Name: {name}'
        self.expectedSerialOne = sn1
        self.expectedSerialOneLabel.value = sn1
        self.expectedSerialTwo = sn2
        self.expectedSerialTwoLabel.value = sn2
        return

There are a few function calls you won't recognize that I have added in overridden widget classes. But nothing that should affect form switching functionality through directly calling the method.

For example, I have overridden each of the text entry widgets to include the following:

def setReturnHandler(self, function):
    handlers = {curses.KEY_ENTER: function,  # By key identity
                curses.ascii.NL: function,  # Unix character
                curses.ascii.CR: function  # NT character
                }
    self.add_handlers(handlers)

def hide(self, state):
    self.hidden = state
    self.display()
    return

def show(self, state):
    self.hidden = not state
    self.display()
    return

def set_editable(self, editable):
    super(TitleText, self).set_editable(editable)
    self.editable = editable
    self.entry_widget.editable = editable
    if(editable):
        self.hidden = False
    return

def set_editing(self, editing):
    if(editing):
        self.set_editable(True)
    self.editing = editing  # Affects the widget title color
    self.entry_widget.editing = editing
    self.display()
    if not editing:
        self.exit()
    else:
        self.edit()
    return

def exit(self):
    self.entry_widget.how_exited = 1
    return
Masterisk
  • 21
  • 3

0 Answers0