I have been teaching myself Python and wanted to create something useful while learning. I am using wxPython to create the interface. The app works if I use the mouse to click the buttons. I've been trying to get it to recognize operation key-ins like addition using the num pad +. It will register the keystrokes but the binding for the event handler to run the operation commands isn't working. I know this isn't the cleanest written code and would also appreciate any advice to clean it. I have the code on github.
The calculator uses RPN similar to an HP48 series calculator and has the display appearance similar to an HP48 as well.

This is the section of code I think is not functioning the way I thought it should for recognizing the operation key-ins. The for loop for buttons1 generates the number pad. The for loop for buttons2 generates the buttons for the calculator operations.

`for row in buttons1:
        for label in row:
            b = wx.Button(self, label=label, size=(40,-1))
            b.Bind(wx.EVT_BUTTON, self.OnButton)                
    sizer.Add(gsizer1, (6,0),(1,1), wx.EXPAND|wx.LEFT|wx.BOTTOM|wx.ALIGN_BOTTOM, 10)

    for row in buttons2:
        for label in row:
            b = wx.Button(self, label=label, size=(60,-1))
            b.Bind(wx.EVT_BUTTON, self.OnButton)
            b.Bind(wx.EVT_KEY_DOWN, self.OnKeyPress)
    sizer.Add(gsizer2, (6,1),(1,1), wx.EXPAND|wx.LEFT|wx.RIGHT|wx.BOTTOM, 10)

def OnKeyPress(self, event):
    keycode = event.GetKeyCode()
    if keycode == wx.WXK_RETURN or wx.WXK_NUMPAD_ENTER:

    elif keycode == wx.WXK_ADD or wx.WXK_NUMPAD_ADD:


It is probably something simple. I just don't have the experience yet to know what it is.

Recommended Answers

All 3 Replies

The result of if keycode == foo or bar is probably not what you are expecting. You probably meant if keycode in (foo, bar)

I updated the if statement to:
'if keycode in (wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER):'
and still doesn't recognize the enter key.

I did some more digging and found I may not have the binding correct. I tried moving the binding to when the TextCtrl is created but the binding overrides regular text input into the control. The code in the OP contains my original attempt. I tried a different attempt but regular input stopped functioning.
This is the revised section:
'self.display = wx.TextCtrl(self, -1, style=wx.TE_RIGHT)
self.display.Bind(wx.EVT_KEY_DOWN, self.OnKeyPress)'

I reduced the program to just the display and input.
I'm pretty sure I'm not binding the TextCtrl correctly but I can't figure out how it should be done so it will recognize =, +, -, etc. as operations and not text input in the display.

import wx
import math
from fractions import Fraction

DISP_COLOR = wx.Colour(243, 248, 205) # Yellowish
STACK4 = 0
STACK3 = 0
STACK2 = 0
STACK1 = 0

class MainFrame(wx.Frame):
    '''Main calculator frame'''
    def __init__(self, *args, **kwargs):
        kwargs.setdefault('title', "Feet-Inch Calculator")
        wx.Frame.__init__(self, *args, **kwargs)
        self.calcPanel = CalcPanel(self)
        fsizer = wx.BoxSizer(wx.VERTICAL)
        fsizer.Add(self.calcPanel, 1, wx.EXPAND, 10)

class CalcPanel(wx.Panel):
    '''Panel containing display, conversion radiobox and buttons'''
    def __init__(self, *args, **kwargs):
        wx.Panel.__init__(self, *args, **kwargs)
        sizer = wx.GridBagSizer(3,2)

        self.display4 = wx.StaticText(self, -1, str(STACK4),
        self.display3 = wx.StaticText(self, -1, str(STACK3), 
        self.display2 = wx.StaticText(self, -1, str(STACK2),
        self.display1 = wx.StaticText(self, -1, str(STACK1),
        self.display = wx.TextCtrl(self, -1, style=wx.TE_RIGHT)
        #self.display.Bind(wx.EVT_KEY_DOWN, self.OnKeyPress)
        self.text4 = wx.StaticText(self, -1, "4:")
        self.text3 = wx.StaticText(self, -1, "3:")
        self.text2 = wx.StaticText(self, -1, "2:")
        self.text1 = wx.StaticText(self, -1, "1:")
        sizer.Add(self.text4, (0,0), (1,1), wx.EXPAND|wx.LEFT|wx.TOP, 10)
        sizer.Add(self.text3, (1,0), (1,1), wx.EXPAND|wx.LEFT, 10)
        sizer.Add(self.text2, (2,0), (1,1), wx.EXPAND|wx.LEFT, 10)
        sizer.Add(self.text1, (3,0), (1,1), wx.EXPAND|wx.LEFT, 10)
        sizer.Add(self.display4, (0,1), (1,1), wx.EXPAND|wx.RIGHT|wx.TOP, 10)
        sizer.Add(self.display3, (1,1), (1,1), wx.EXPAND|wx.RIGHT, 10)
        sizer.Add(self.display2, (2,1), (1,1), wx.EXPAND|wx.RIGHT, 10)
        sizer.Add(self.display1, (3,1), (1,1), wx.EXPAND|wx.RIGHT, 10)
        sizer.Add(self.display, (4,0), (1,2), wx.EXPAND|wx.RIGHT|wx.LEFT, 10)

    def OnKeyPress(self, event):
        keycode = event.GetKeyCode()
        if keycode in (wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER):

        elif keycode in (wx.WXK_ADD, wx.WXK_NUMPAD_ADD):

    def enter(self):
        """ enter a new number to the stack"""
        global STACK1, STACK2, STACK3, STACK4
        if self.display.GetValue() != "":
            STACK4 = STACK3
            STACK3 = STACK2
            STACK2 = STACK1
            STACK1 = self.frac_to_decimal()
            STACK4 = STACK3
            STACK3 = STACK2
            STACK2 = STACK1
            STACK1 = 0

    def add(self):
        """ add stack1 and display or contents of stack"""
        global STACK1, STACK2, STACK3, STACK4
        if self.display.GetValue() != "":
            STACK1 = STACK1 + self.frac_to_decimal()
            STACK1 = STACK2 + STACK1
            STACK2 = STACK3
            STACK3 = STACK4
            STACK4 = 0

    def updateDisplay(self):
        """ update display """
        global STACK1, STACK2, STACK3, STACK4
        if self.rbox.GetSelection() == 0:
            S4 = self.fraction_str(STACK4)
            S3 = self.fraction_str(STACK3)
            S2 = self.fraction_str(STACK2)
            S1 = self.fraction_str(STACK1)
        elif self.rbox.GetSelection() == 1:
            S4 = str(STACK4 * 12)
            S3 = str(STACK3 * 12)
            S2 = str(STACK2 * 12)
            S1 = str(STACK1 * 12)
            S4 = str(STACK4)
            S3 = str(STACK3)
            S2 = str(STACK2)
            S1 = str(STACK1)


if __name__ == '__main__':
    calculator = wx.App(False)
    calc = MainFrame(None)
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.