-1

I am using Python Tkinter 3.7 to make my GUI calculator. For my assessment, I need to implement keyboard function keys that will also type in digits and a backspace button that removes the last digit or operator entered, however, I could not figure out how to do add bind and a backspace in tkinter. I have added annotation to show how I went forward with this.

def cb(bs):           #cb=click on btn, bs=btn stuff
    global bd         # bd = stores & accum rcvd btn data
    bd=bd+str(bs) # bd=itself+the new bs(btn stuff)
    tv.set(bd)        # at some point clear out bd

def klr():
    global bd    # the accumulator of all btn data sent to cb()
    bd=''           # set bd to nothing
    tv.set(bd)   # tv var is bound to the text box: 'textvariable'

def eqf():
    global bd
    bd=eval(bd)
    tv.set(bd)
    bd=''

root = Tk()
root.title("Me Calculator")
tv=StringVar()
global bd    # bd = will store accumulated button data
bd=''           # bd = initially set to nothing



# textbox variable: tb
tb = Entry(root,font=('arial',18,'bold'),
           textvariable=tv,
           bd=15,
           insertwidth=3,
           bg='lightblue',
           justify='right').grid(columnspan=4)

tv.set('0.0')


# buttons section
btn7=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='7',
            command=lambda:cb(7)).grid(row=1,column=0)
btn8=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='8',
            command=lambda:cb(8)).grid(row=1,column=1)
btn9=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='9',
            command=lambda:cb(9)).grid(row=1,column=2)
divbtn=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='/',
    command=lambda:cb('/')).grid(row=1,column=3)
####
btn4=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='4',
            command=lambda:cb(4)).grid(row=2,column=0)
btn5=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='5',
            command=lambda:cb(5)).grid(row=2,column=1)
btn6=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='6',
            command=lambda:cb(6)).grid(row=2,column=2)
mulbtn=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='*',
            command=lambda:cb('*')).grid(row=2,column=3)

######




btn1=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='1',
            command=lambda:cb(1)).grid(row=3,column=0)
btn2=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='2',
            command=lambda:cb(2)).grid(row=3,column=1)
btn3=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='3',
            command=lambda:cb(3)).grid(row=3,column=2)
subtn=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='-',
            command=lambda:cb('-')).grid(row=3,column=3)


btn0=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='0',
            command=lambda:cb(0)).grid(row=4,column=0)
decbtn=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='.',
            command=lambda:cb('.')).grid(row=4,column=1)
addbtn=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='+',
            command=lambda:cb('+')).grid(row=4,column=2)

eqbtn=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='=',
            command=lambda:eqf()).grid(row=4,column=3)

klrbtn=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='Clear',
            command=lambda:klr()).grid(row=4,column=4)
root.mainloop()

3 Answers3

0

Maybe this:

from tkinter import *;
def cb(bs):           #cb=click on btn, bs=btn stuff
    global bd         # bd = stores & accum rcvd btn data
    bd=bd+str(bs) # bd=itself+the new bs(btn stuff)
    tv.set(bd)        # at some point clear out bd

def klr():
    global bd    # the accumulator of all btn data sent to cb()
    bd=''           # set bd to nothing
    tv.set(bd)   # tv var is bound to the text box: 'textvariable'

def eqf():
    global bd
    bd=eval(bd)
    tv.set(bd)
    bd=''

def bck(): # function to operate
    global bd
    bd=str(bd)[0:-1] # We get bd from first car to preast
    tv.set(bd)

root = Tk()
root.title("Me Calculator")
tv=StringVar()
global bd    # bd = will store accumulated button data
bd=''           # bd = initially set to nothing



# textbox variable: tb
tb = Entry(root,font=('arial',18,'bold'),
           textvariable=tv,
           bd=15,
           insertwidth=3,
           bg='lightblue',
           justify='right').grid(columnspan=4)

tv.set('0.0')


# buttons section
btn7=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='7',
            command=lambda:cb(7)).grid(row=1,column=0)
btn8=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='8',
            command=lambda:cb(8)).grid(row=1,column=1)
btn9=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='9',
            command=lambda:cb(9)).grid(row=1,column=2)
divbtn=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='/',
    command=lambda:cb('/')).grid(row=1,column=3)
####
btn4=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='4',
            command=lambda:cb(4)).grid(row=2,column=0)
btn5=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='5',
            command=lambda:cb(5)).grid(row=2,column=1)
btn6=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='6',
            command=lambda:cb(6)).grid(row=2,column=2)
mulbtn=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='*',
            command=lambda:cb('*')).grid(row=2,column=3)

######




btn1=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='1',
            command=lambda:cb(1)).grid(row=3,column=0)
btn2=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='2',
            command=lambda:cb(2)).grid(row=3,column=1)
btn3=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='3',
            command=lambda:cb(3)).grid(row=3,column=2)
subtn=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='-',
            command=lambda:cb('-')).grid(row=3,column=3)


btn0=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='0',
            command=lambda:cb(0)).grid(row=4,column=0)
decbtn=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='.',
            command=lambda:cb('.')).grid(row=4,column=1)
addbtn=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='+',
            command=lambda:cb('+')).grid(row=4,column=2)

eqbtn=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='=',
            command=lambda:eqf()).grid(row=4,column=3)

klrbtn=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='Clear',
            command=lambda:klr()).grid(row=4,column=4)

# My addon
klrbtn=Button(root,padx=5,bd=8,
            fg="black",font=('arial',24,'bold'),
            text='Backs',
            command=lambda:bck()).grid(row=3,column=4)

root.mainloop()
ISD
  • 984
  • 1
  • 6
  • 21
0

You can use root.bind('<Return>', functionReturn) and root.bind('<BackSpace>', functionBackSpace)

And defining the function with event as their argument:

def functionReturn(event): #your code for return here def functionBackSpace(event): #your code for backspace here

(see https://stackoverflow.com/a/43920993/12141765 and https://stackoverflow.com/a/16996475/12141765 for detailed answers)

Logi
  • 26
  • 4
  • When you define the function you call with backspace (in your case it seems to be the function `clear_backspace`), you have to put `event` in its definition. It should be something like this: `def clear_backspace(event): #your code for backspace here` – Logi Oct 01 '19 at 16:18
  • Your button press function requires an argument you defined as num. `root.bind('<1>', lambda event: button_press(1))` works well in your code. – Logi Oct 02 '19 at 08:27
  • Seeing you are using lots of global variables, you should consider defining your functions in a class (avoiding the global variables): https://stackoverflow.com/a/58171862/12141765 – Logi Oct 02 '19 at 08:31
0

I just defined a back function under clear that uses str[:-1] -1 is just the END of the str because it start from the opposite side

def back():
    global bd
    bd = bd[:-1]
    tv.set(bd)

Then I made the button. Btw the button grid I used doesn't look the best

backspace = Button(root, padx=5, bd=8,
               fg="black", font=('arial', 24, 'bold'),
               text='Back',
               command=lambda: back()).grid(row=3, column=4)
FastFinge
  • 54
  • 3