Tkinter, a lot of buttons, make prog shorter?

S

skanemupp

is there anyway to make this shorter? i hate having these big blocks
of similar-looking code, very unaesthetic.
maybe doesnt matter good-code-wise?
anyway can i make some function that makes this shorter?
like put the etiquettes on the button froma string of
'123+456-789*0Cr/' ?
problem is the command and lambda-func for each button is different.


self.btnDisplay = Button(self,text='1',command=lambda
n="1":self.Display(n),width=2,height=2)
self.btnDisplay.grid(row=3, column=0)

self.btnDisplay = Button(self,text='2',command=lambda
n="2":self.Display(n),width=2,height=2)
self.btnDisplay.grid(row=3, column=1)

self.btnDisplay = Button(self,text='3',command=lambda
n="3":self.Display(n),width=2,height=2)
self.btnDisplay.grid(row=3, column=2)

self.btnDisplay = Button(self,text='+',command=lambda
n="+":self.Display(n),width=2,height=2)
self.btnDisplay.grid(row=3, column=3)

self.btnDisplay = Button(self,text='4',command=lambda
n="4":self.Display(n),width=2,height=2)
self.btnDisplay.grid(row=4, column=0)

self.btnDisplay = Button(self,text='5',command=lambda
n="5":self.Display(n),width=2,height=2)
self.btnDisplay.grid(row=4, column=1)

self.btnDisplay = Button(self,text='6',command=lambda
n="6":self.Display(n),width=2,height=2)
self.btnDisplay.grid(row=4, column=2)

self.btnDisplay = Button(self,text='-',command=lambda
n="-":self.Display(n),width=2,height=2)
self.btnDisplay.grid(row=4, column=3)

self.btnDisplay = Button(self,text='7',command=lambda
n="7":self.Display(n),width=2,height=2)
self.btnDisplay.grid(row=5, column=0)

self.btnDisplay = Button(self,text='8',command=lambda
n="8":self.Display(n),width=2,height=2)
self.btnDisplay.grid(row=5, column=1)

self.btnDisplay = Button(self,text='9',command=lambda
n="9":self.Display(n),width=2,height=2)
self.btnDisplay.grid(row=5, column=2)

self.btnDisplay = Button(self,text='*',command=lambda
n="*":self.Display(n),width=2,height=2)
self.btnDisplay.grid(row=5, column=3)

self.btnDisplay = Button(self,text='0',command=lambda
n="0":self.Display(n),width=2,height=2)
self.btnDisplay.grid(row=6, column=0)

self.btnDisplay =
Button(self,text='C',command=self.Clean,width=2,height=2)
self.btnDisplay.grid(row=6, column=1)

self.btnDisplay = Button(self,text='r',command=lambda
n="r":self.Display(n),width=2,height=2)
self.btnDisplay.grid(row=6, column=2)

self.btnDisplay = Button(self,text='/',command=lambda
n="/":self.Display(n),width=2,height=2)
self.btnDisplay.grid(row=6, column=3)
 
T

Terry Reedy

| is there anyway to make this shorter? i hate having these big blocks
| of similar-looking code, very unaesthetic.
| maybe doesnt matter good-code-wise?
| anyway can i make some function that makes this shorter?
| like put the etiquettes on the button froma string of
| '123+456-789*0Cr/' ?
| problem is the command and lambda-func for each button is different.
|
|
| self.btnDisplay = Button(self,text='1',command=lambda
| n="1":self.Display(n),width=2,height=2)
| self.btnDisplay.grid(row=3, column=0)
|
| self.btnDisplay = Button(self,text='2',command=lambda
| n="2":self.Display(n),width=2,height=2)
| self.btnDisplay.grid(row=3, column=1)
|
| self.btnDisplay = Button(self,text='3',command=lambda
| n="3":self.Display(n),width=2,height=2)
| self.btnDisplay.grid(row=3, column=2)
|
| self.btnDisplay = Button(self,text='+',command=lambda
| n="+":self.Display(n),width=2,height=2)
| self.btnDisplay.grid(row=3, column=3)
|
| self.btnDisplay = Button(self,text='4',command=lambda
| n="4":self.Display(n),width=2,height=2)
| self.btnDisplay.grid(row=4, column=0)
|
| self.btnDisplay = Button(self,text='5',command=lambda
| n="5":self.Display(n),width=2,height=2)
| self.btnDisplay.grid(row=4, column=1)
|
| self.btnDisplay = Button(self,text='6',command=lambda
| n="6":self.Display(n),width=2,height=2)
| self.btnDisplay.grid(row=4, column=2)
|
| self.btnDisplay = Button(self,text='-',command=lambda
| n="-":self.Display(n),width=2,height=2)
| self.btnDisplay.grid(row=4, column=3)
|
| self.btnDisplay = Button(self,text='7',command=lambda
| n="7":self.Display(n),width=2,height=2)
| self.btnDisplay.grid(row=5, column=0)
|
| self.btnDisplay = Button(self,text='8',command=lambda
| n="8":self.Display(n),width=2,height=2)
| self.btnDisplay.grid(row=5, column=1)
|
| self.btnDisplay = Button(self,text='9',command=lambda
| n="9":self.Display(n),width=2,height=2)
| self.btnDisplay.grid(row=5, column=2)
|
| self.btnDisplay = Button(self,text='*',command=lambda
| n="*":self.Display(n),width=2,height=2)
| self.btnDisplay.grid(row=5, column=3)
|
| self.btnDisplay = Button(self,text='0',command=lambda
| n="0":self.Display(n),width=2,height=2)
| self.btnDisplay.grid(row=6, column=0)
|
| self.btnDisplay =
| Button(self,text='C',command=self.Clean,width=2,height=2)
| self.btnDisplay.grid(row=6, column=1)
|
| self.btnDisplay = Button(self,text='r',command=lambda
| n="r":self.Display(n),width=2,height=2)
| self.btnDisplay.grid(row=6, column=2)
|
| self.btnDisplay = Button(self,text='/',command=lambda
| n="/":self.Display(n),width=2,height=2)
| self.btnDisplay.grid(row=6, column=3)

With the exception of the 'C' button, the only thing different is the label
and position.
I believe (untested, obviously)

def btn(self, txt, r, c):
self.btnDisplay = Button(self, text=txt, command=lambda:
self.Display(txt), width=2,height=2)
self.btnDisplay.grid(row=r, column=r)

will work.

tjr
 
P

Peter Otten

is there anyway to make this shorter? i hate having these big blocks
of similar-looking code, very unaesthetic.
maybe doesnt matter good-code-wise?
anyway can i make some function that makes this shorter?
like put the etiquettes on the button froma string of
'123+456-789*0Cr/' ?
problem is the command and lambda-func for each button is different.

You can look up the command in a dictionary:

commands = {"C": self.Clean}
top = 3
for i, text in enumerate("123+456-789*0Cr/"):
row, column = divmod(i, 4)
try:
command = commands[text]
except KeyError:
def command(n=text):
self.Display(n)
button = Button(self, text=text, command=command, width=2, height=2)
button.grid(row=top+row, column=column)

The problem with this is that the shorter code may take a bit longer to
understand, so that there is no net win for the reader. A compromise would be
to define a helper function:

def make_button(self, row, column, text, command):
# implementation left as an exercise

# use it:
self.make_button(3, 0, "1", lambda n="1": ...)
self.make_button(3, 1, "2", lambda n="2": ...)
....

Peter
 
7

7stud

is there anyway to make this shorter? i hate having these big blocks
of similar-looking code, very unaesthetic.
maybe doesnt matter good-code-wise?
anyway can i make some function that makes this shorter?
like put the etiquettes on the button froma string of
'123+456-789*0Cr/' ?
problem is the command and lambda-func for each button is different.

        self.btnDisplay = Button(self,text='1',command=lambda
n="1":self.Display(n),width=2,height=2)
        self.btnDisplay.grid(row=3, column=0)

        self.btnDisplay = Button(self,text='2',command=lambda
n="2":self.Display(n),width=2,height=2)
        self.btnDisplay.grid(row=3, column=1)

        self.btnDisplay = Button(self,text='3',command=lambda
n="3":self.Display(n),width=2,height=2)
        self.btnDisplay.grid(row=3, column=2)

        self.btnDisplay = Button(self,text='+',command=lambda
n="+":self.Display(n),width=2,height=2)
        self.btnDisplay.grid(row=3, column=3)

        self.btnDisplay = Button(self,text='4',command=lambda
n="4":self.Display(n),width=2,height=2)
        self.btnDisplay.grid(row=4, column=0)

        self.btnDisplay = Button(self,text='5',command=lambda
n="5":self.Display(n),width=2,height=2)
        self.btnDisplay.grid(row=4, column=1)

        self.btnDisplay = Button(self,text='6',command=lambda
n="6":self.Display(n),width=2,height=2)
        self.btnDisplay.grid(row=4, column=2)

        self.btnDisplay = Button(self,text='-',command=lambda
n="-":self.Display(n),width=2,height=2)
        self.btnDisplay.grid(row=4, column=3)

        self.btnDisplay = Button(self,text='7',command=lambda
n="7":self.Display(n),width=2,height=2)
        self.btnDisplay.grid(row=5, column=0)

        self.btnDisplay = Button(self,text='8',command=lambda
n="8":self.Display(n),width=2,height=2)
        self.btnDisplay.grid(row=5, column=1)

        self.btnDisplay = Button(self,text='9',command=lambda
n="9":self.Display(n),width=2,height=2)
        self.btnDisplay.grid(row=5, column=2)

        self.btnDisplay = Button(self,text='*',command=lambda
n="*":self.Display(n),width=2,height=2)
        self.btnDisplay.grid(row=5, column=3)

        self.btnDisplay = Button(self,text='0',command=lambda
n="0":self.Display(n),width=2,height=2)
        self.btnDisplay.grid(row=6, column=0)

        self.btnDisplay =
Button(self,text='C',command=self.Clean,width=2,height=2)
        self.btnDisplay.grid(row=6, column=1)

        self.btnDisplay = Button(self,text='r',command=lambda
n="r":self.Display(n),width=2,height=2)
        self.btnDisplay.grid(row=6, column=2)

        self.btnDisplay = Button(self,text='/',command=lambda
n="/":self.Display(n),width=2,height=2)
        self.btnDisplay.grid(row=6, column=3)

You said you were an experienced programmer, but you keep posting code
with the same mistakes over and over again. Why are you attaching the
buttons to self?
 
7

7stud

You said you were an experienced programmer, but you keep posting code
with the same mistakes over and over again.  Why are you attaching the
buttons to self?

Remember this:
 
S

skanemupp

should i not use self. in Clean() and Calculate() either?

anyway i had changed it before. must have copied the wrong program.



#! /usr/bin/env python
from Tkinter import *
import tkMessageBox

class GUIFramework(Frame):
"""This is the GUI"""

def __init__(self, master=None):
"""Initialize yourself"""

self.expr = ""

"""Initialise the base class"""
Frame.__init__(self,master)

"""Set the Window Title"""
self.master.title("Calculator")

"""Display the main window"
with a little bit of padding"""
self.grid(padx=10,pady=10)
self.CreateWidgets()



def CreateWidgets(self):

"""Create the Button, set the text and the
command that will be called when the button is clicked"""
btnDisplay = Button(self, text="calculate!",
command=self.Calculate)
btnDisplay.grid(row=0, column=31)

## """Create the Button, set the text and the
## command that will be called when the button is clicked"""
## self.lbText = Label(self, text="Results:")
## self.lbText.grid(row=1, column=0)


btnDisplay = Button(self,text='1',command=lambda
n="1":self.Display(n),width=2,height=2)
btnDisplay.grid(row=3, column=0)

btnDisplay = Button(self,text='2',command=lambda
n="2":self.Display(n),width=2,height=2)
btnDisplay.grid(row=3, column=1)

btnDisplay = Button(self,text='3',command=lambda
n="3":self.Display(n),width=2,height=2)
btnDisplay.grid(row=3, column=2)

btnDisplay = Button(self,text='+',command=lambda
n="+":self.Display(n),width=2,height=2)
btnDisplay.grid(row=3, column=3)

btnDisplay = Button(self,text='4',command=lambda
n="4":self.Display(n),width=2,height=2)
btnDisplay.grid(row=4, column=0)

btnDisplay = Button(self,text='5',command=lambda
n="5":self.Display(n),width=2,height=2)
btnDisplay.grid(row=4, column=1)

btnDisplay = Button(self,text='6',command=lambda
n="6":self.Display(n),width=2,height=2)
btnDisplay.grid(row=4, column=2)

btnDisplay = Button(self,text='-',command=lambda
n="-":self.Display(n),width=2,height=2)
btnDisplay.grid(row=4, column=3)

btnDisplay = Button(self,text='7',command=lambda
n="7":self.Display(n),width=2,height=2)
btnDisplay.grid(row=5, column=0)

btnDisplay = Button(self,text='8',command=lambda
n="8":self.Display(n),width=2,height=2)
btnDisplay.grid(row=5, column=1)

btnDisplay = Button(self,text='9',command=lambda
n="9":self.Display(n),width=2,height=2)
btnDisplay.grid(row=5, column=2)

btnDisplay = Button(self,text='*',command=lambda
n="*":self.Display(n),width=2,height=2)
btnDisplay.grid(row=5, column=3)

btnDisplay = Button(self,text='0',command=lambda
n="0":self.Display(n),width=2,height=2)
btnDisplay.grid(row=6, column=0)

btnDisplay =
Button(self,text='C',command=self.Clean,width=2,height=2)
btnDisplay.grid(row=6, column=1)

btnDisplay = Button(self,text='^.5',command=lambda n="**.
5":self.Display(n),width=2,height=2)
btnDisplay.grid(row=6, column=2)

btnDisplay = Button(self,text='/',command=lambda
n="/":self.Display(n),width=2,height=2)
btnDisplay.grid(row=6, column=3)




def Display(self, number):
self.expr = self.expr + number
self.lbText = Label(self, text=self.expr)
self.lbText.grid(row=0, column=0)

def Calculate(self):
self.expr = str(eval(self.expr))#try catch tex 3+6+
result = self.expr
self.Clean()
self.lbText = Label(self, text=result)
self.lbText.grid(row=0, column=0)
self.expr = ""

def Clean(self):
self.expr = " "
self.lbText.config(text=self.expr)
self.lbText = Label(self, text=self.expr)
self.lbText.grid(row=0, column=0)
self.expr = ""
self.lbText.config(text=self.expr)
self.lbText = Label(self, text=self.expr)
self.lbText.grid(row=0, column=0)



if __name__ == "__main__":
guiFrame = GUIFramework()
guiFrame.mainloop()
 
7

7stud

should i not use self. in Clean() and Calculate() either?

You probably shouldn't be using classes at all. When you are trying
to learn the basics of a language, you don't want to complicate things
further with classes. Copying a program off the internet and trying
to modify it for your own purposes is usually going to be a lot more
work than writing the whole thing from scratch yourself. In addition,
when you write the whole thing yourself, you'll have a better
understanding of how things work.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,989
Messages
2,570,207
Members
46,782
Latest member
ThomasGex

Latest Threads

Top