Little, by little my calculator is getting a look I want.
However, I find that using Tkinter is not very intuitive, and i cannot find detail documentation.
have a look at this

# menu-example-2.py

#from Tkinter import *

#root = Tk()

#def hello():
    #print "hello!"

## create a toplevel menu
#try:
  #menubar = Menu(root)
#except: pass
#menubar.add_command(label="Hello!", command=hello)
#menubar.add_command(label="Quit!", command=root.quit)

## display the menu
#root.config(menu=menubar)

#mainloop()

from Tkinter import *

class CalcApp:
  
  def __init__ ( self, parent ):
    #define menubar
    try:
      self.menubar = Menu ( parent )
    except: pass
    #create edit menu
    self.edit_menu = Menu ( self.menubar, tearoff = 0 )
    self.edit_menu.add_command ( label = "Copy", command = self.hello )
    self.edit_menu.add_command ( label = "Paste", command = self.hello )
    self.menubar.add_cascade ( label = "Edit", menu = self.edit_menu )
    
    #create about
    self.menubar.add_command ( label = "About", command = self.hello )
    parent.config ( menu = self.menubar )
    
    #define how main windwow will look
    parent.title ( "Calculator" )
    parent.geometry ( "255x228+0+0" )
    parent.resizable ( width = False, height = False )
    
    try:
      self.fr_entry = Frame ( parent )#here, I tried to define height and width, but no luck
    except: pass
    self.fr_entry. pack ( )
    self.entry = Entry ( self.fr_entry, justify = "right", width = 45, relief = "groove" )
    self.entry.focus_force ( )
    self.entry.pack ( )
    
    
  def hello ( self ):
    print "hello"
    
root = Tk ( )
calc = CalcApp ( root )
root.mainloop ( )

Now I want to disable user to enter more than 20 numbers (numbers only) and I want to make Entry field a little more in height, just like win calcluator?

Recommended Answers

All 14 Replies

Hi!

I want to make Entry field a little more in height

:) An Entry has height = 1 per definition. If you want a bigger one, you'll have to use a Text-Widget.

self.fr_entry = Frame ( parent )#here, I tried to define height and width, but no luck

A Frame is a Container-Widget. It is always as big, as the Widgets it contains.

However, I find that using Tkinter is not very intuitive,

I hear this quite often. For me, Tkinter is the easiest GUI-Toolkit to use, but that's mostly a matter of taste.

and i cannot find detail documentation.

No? Do you know this one? You find it when you just follow the links at www.python.org :)
Anyway, if you have questions, just post them here, we'll try our best to help you ;)

Regards, mawe

Thanks for reply, I have downloaded "an Introduction to Tkinter" and I'll read it througly. Prviously, I used Thinking in Tkinter and it's tutorial, aslo I fond a lot of materials and tutorials, but I didn't find "official documentation" in which every widgets and it's properties are explained. Anyway, thank you. I guess I'll need to spend more time to read and learn about different widgets, and then try to use it, maybe it will be more efficient.
I used to read MSDN and find it very well organized when I learned basics of Win API and Socket programming, and i hoped there are something similar about Tkinter.

Cheers

I guess I'll need to spend more time to read and learn about different widgets, and then try to use it, maybe it will be more efficient.

Hm, don't know. There are so many snippets and programs using Tkinter. I learned most by reading and experimenting with this code.

Have a look at the german Python-Forum. In the Codesnippets and Showcase you'll find lots of Tkinter code, e.g. some useless games written by me :D This might give you an expression of what is possible with Tkinter and how it is done.

Micko, why do you want to use a Frame?

Using a Frame is ok, it makes the application more flexible. You could then easily switch between 2 or more Button-layouts (e.g. normal and scientific). All you have to do is create the two Frames and pack all the buttons into them. When you want to switch them, just use pack_forget() at the current one, and pack() on the other one. Voila! ;)

Unfortunately,after reading about Text widgets, I'm unable to make sure that user can enter only 20 digits and not letters or other nondigits into Text widgets, it's very complicated, so I guess, I'll try to switch to wxPython. At first glance it seems more intuitive.
Thank you for help mawe, I really appreciate it, but some things are just not meant to be... :)

I'm unable to make sure that user can enter only 20 digits and not letters or other nondigits into Text widgets, it's very complicated, so I guess, I'll try to switch to wxPython

Is this easy with wxPython?

In Tkinter I would probably do it like this:
Bind keypresses to the Text widget. If the pressed key is a digit and the text in the Text widget is shorter than 20, insert the digit. Otherwise do nothing.
Doesn't seem to be too complicated.

But as I said, choosing a GUI toolkit is a matter of taste. So try wxPython, maybe you like it better.

Thank you for your effort.
Actually, this is what I manage to do so far. I assume it's possible to put a lot of this in loops, but since this is only very beginner's I think it's OK.

from Tkinter import *
from __future__ import division

class CalcApp:
  
  def __init__ ( self, parent ):
    #define menubar
    try:
      self.menubar = Menu ( parent )
    except: pass
    #create edit menu
    self.edit_menu = Menu ( self.menubar, tearoff = 0 )
    self.edit_menu.add_command ( label = "Copy" )
    self.edit_menu.add_command ( label = "Paste" )
    self.menubar.add_cascade ( label = "Edit" )
    
    #create about
    self.menubar.add_command ( label = "About" )
    parent.config ( menu = self.menubar )
    
    #define how main windwow will look
    parent.title ( "Calculator" )
    parent.geometry ( "160x200+0+0" )
    parent.resizable ( width = False, height = False )
    
    try:
      self.fr_entry = Frame ( parent )#here, I tried to define height and width, but no luck
    except: pass
    self.fr_entry. pack ( )
    self.entry = Entry ( self.fr_entry, justify = "right", width = 45, relief = "groove", borderwidth = 2 )
    self.entry.focus_force ( )
    self.entry.pack ( )
    
    try:
      self.fr_but789 = Frame ( self.fr_entry )
    except: pass
    self.fr_but789. pack ( )
    
    self.button7 = Button (self.fr_but789, text = "7" , width = 5, height = 2, command = self. insert_7 )
    self.button7.pack (side = LEFT )
    self.button8 = Button (self.fr_but789, text = "8" , width = 5, height = 2, command = self. insert_8 )
    self.button8.pack (side = LEFT )
    self.button9 = Button (self.fr_but789, text = "9" , width = 5, height = 2, command = self. insert_9)
    self.button9.pack (side = LEFT )
    self.button_div = Button (self.fr_but789, text = "/" , width = 5, height = 2, command = self. insert_div )
    self.button_div.pack (side = LEFT )
    
    try:
      self.fr_but456 = Frame ( self.fr_entry )
    except: pass
    self.fr_but456. pack ( )
    
    self.button4 = Button (self.fr_but456, text = "4" , width = 5, height = 2, command = self. insert_4 )
    self.button4.pack (side = LEFT )
    self.button5 = Button (self.fr_but456, text = "5" , width = 5, height = 2, command = self. insert_5 )
    self.button5.pack (side = LEFT )
    self.button6 = Button (self.fr_but456, text = "6" , width = 5, height = 2, command = self. insert_6)
    self.button6.pack (side = LEFT )
    self.button_mul = Button (self.fr_but456, text = "*" , width = 5, height = 2, command = self. insert_mul )
    self.button_mul.pack (side = LEFT )
    
    try:
      self.fr_but123 = Frame ( self.fr_entry )
    except: pass
    self.fr_but123. pack ( )
    
    self.button1 = Button (self.fr_but123, text = "1" , width = 5, height = 2, command = self. insert_1 )
    self.button1.pack (side = LEFT )
    self.button2 = Button (self.fr_but123, text = "2" , width = 5, height = 2, command = self. insert_2 )
    self.button2.pack (side = LEFT )
    self.button3 = Button (self.fr_but123, text = "3" , width = 5, height = 2, command = self. insert_3 )
    self.button3.pack (side = LEFT )
    self.button_sub = Button (self.fr_but123, text = "-" , width = 5, height = 2, command = self. insert_sub)
    self.button_sub.pack (side = LEFT )
    
    
    try:
      self.fr_but0 = Frame ( self.fr_entry )
    except: pass
    self.fr_but0. pack ( )
    
    self.button0 = Button (self.fr_but0, text = "0" , width = 5, height = 2, command = self. insert_0 )
    self.button0.pack (side = LEFT )
    self.button_sign = Button (self.fr_but0, text = "+/-" , width = 5, height = 2, command = self. insert_sign )
    self.button_sign.pack (side = LEFT )
    self.button_point = Button (self.fr_but0, text = "." , width = 5, height = 2, command = self. insert_point )
    self.button_point.pack (side = LEFT )
    self.button_add = Button (self.fr_but0, text = "+" , width = 5, height = 2, command = self. insert_add )
    self.button_add.pack (side = LEFT )
    
    try:
      self.fr_but_equal = Frame ( self.fr_entry )
    except: pass
    self.fr_but_equal. pack ( )
    
    self.button_equal = Button (self.fr_but_equal, text = "=", width = 25, height = 2, command = self.evaluate )
    self.button_equal.pack (side = LEFT )
    
    
    
  def insert_7 ( self ):
    self.entry.insert (END, "7")
  def insert_8 ( self ):
    self.entry.insert (END, "8")
  def insert_9 ( self ):
    self.entry.insert (END, "9")
  def insert_div ( self ):
    self.entry.insert (END, "/")
  def insert_4 ( self ):
    self.entry.insert (END, "4")
  def insert_5 ( self ):
    self.entry.insert (END, "5")
  def insert_6 ( self ):
    self.entry.insert (END, "6")
  def insert_mul ( self ):
    self.entry.insert (END, "*")
  def insert_1 ( self ):
    self.entry.insert (END, "1")
  def insert_2 ( self ):
    self.entry.insert (END, "2")
  def insert_3 ( self ):
    self.entry.insert (END, "3")
  def insert_sub ( self ):
    self.entry.insert (END, "-")
  def insert_0 ( self ):
    self.entry.insert (END, "0")
  def insert_sign ( self ):
    str = self.entry.get ( )
    if str == None: 
      pass
    elif str != None and str[0] == "-":
      self.entry.delete (0, 1)
    else:
      self.entry.insert (ANCHOR, "-" )
  def insert_point ( self ):
    self.entry.insert(END, ".") 
  def insert_add ( self ):
    self.entry.insert (END, "+") 
  def evaluate ( self ):
    str = self.entry.get ( )
    try:
      x = eval ( str )
    except SyntaxError:
      print "Syntax Error!"
      return 
    self.entry.delete ( 0, END )
    self.entry.insert (END, x )
  
root = Tk ( )
calc = CalcApp ( root )
root.mainloop ( )

I thought about similar solution, but I tried to figure out how to use all that tags and options in Text widgets, I think it's possible to achive this by only using options and tags, but...

I'm doing this only two days, maybe I need more time...

Here's what I have tried:

...
self.entry.bind ( "<Key>", self.check_input )
...

def check_input ( self, event ):
    str = "0123456789+-*/."
    if event.char not in str : 
      #print event.char
      #Something to do here...
      self.entry.delete ( 0, END )#but this doesn't help much
    else:
      print "It's number"

But this doesn't help much. One item always stay in entry text field....

In Tkinter I would probably do it like this:
Bind keypresses to the Text widget. If the pressed key is a digit and the text in the Text widget is shorter than 20, insert the digit. Otherwise do nothing.
Doesn't seem to be too complicated.

Can you show me a little code snippet that will do that in Tkinter?
Thanks

Hmm, was harder than I thought.
Here's a hack for an Entry, I haven't tested if something similar works with a Text-widget:

from Tkinter import *

class CalculatorDisplay(Entry):
    def __init__(self):
        Entry.__init__(self,
                bg="white",
                validate="key",
                validatecommand=self.validate)

    def keypress(self, event):
        self.lastkey = event.char

    def validate(self, *args):
        if len(self.get()) < 20 and self.lastkey in "1234567890+-*/":
            return True
        return False

root = Tk()

display = CalculatorDisplay()
display.grid(row=0,column=0,columnspan=4)
display.bind("<Key>", display.keypress)

root.mainloop()

Thanks mawe, I really appreciate your help.

Another alternative could allso be to use the wxpython library which has a more 'native' feel on Windows.
YFYI

Rony

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.