TKinter, buttonwidget response problem(1) and all btns the same size(2)!
skanemupp at yahoo.se
skanemupp at yahoo.se
Sat Apr 5 01:02:45 EDT 2008
On 5 Apr, 05:57, skanem... at yahoo.se wrote:
> On 5 Apr, 05:26, 7stud <bbxx789_0... at yahoo.com> wrote:
>
>
>
> > On Apr 4, 7:06 pm, skanem... at yahoo.se wrote:
>
> > > 1st question:
>
> > > when i run this program 1 will be printed into the interpreter when i
> > > run it BUT without me clicking the actual button.
> > > when i then click the button "1", nothing happens.
>
> > > obv i dont want any output when i dont push the button but i want it
> > > when i do.
>
> > > what am i doing wrong here?
>
> > > 2nd question:
>
> > > i want all the buttons to have the same size. i thought i should use
> > > row/columnspan but i dont get that to work.
> > > how should i do?
>
> > > [code]
> > > #! /usr/bin/env python
> > > from Tkinter import *
> > > import tkMessageBox
>
> > > class GUIFramework(Frame):
> > > """This is the GUI"""
>
> > > def __init__(self,master=None):
> > > """Initialize yourself"""
>
> > > """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):
>
> > > self.enText = Entry(self)
> > > self.enText.grid(row=0, column=0, columnspan=8, padx=5,
> > > pady=5)
>
> > > self.enText = Entry(self)
> > > self.enText.grid(row=1, column=0, columnspan=8, padx=5,
> > > pady=5)
>
> > > self.btnDisplay = Button(self, text="1",
> > > command=self.Display(1))
> > > self.btnDisplay.grid(row=3, column=0, padx=5, pady=5)
>
> > > self.btnDisplay = Button(self, text="2", default=ACTIVE)
> > > self.btnDisplay.grid(row=3, column=1, padx=5, pady=5)
>
> > > self.btnDisplay = Button(self, text="3", default=ACTIVE)
> > > self.btnDisplay.grid(row=3, column=2, padx=5, pady=5)
>
> > > self.btnDisplay = Button(self, text="+", default=ACTIVE)
> > > self.btnDisplay.grid(row=3, column=3, padx=5, pady=5)
>
> > > self.btnDisplay = Button(self, text="4", default=ACTIVE)
> > > self.btnDisplay.grid(row=4, column=0, padx=5, pady=5)
>
> > > self.btnDisplay = Button(self, text="5", default=ACTIVE)
> > > self.btnDisplay.grid(row=4, column=1, padx=5, pady=5)
>
> > > self.btnDisplay = Button(self, text="6", default=ACTIVE)
> > > self.btnDisplay.grid(row=4, column=2, padx=5, pady=5)
>
> > > self.btnDisplay = Button(self, text="-", default=ACTIVE)
> > > self.btnDisplay.grid(row=4, column=3, padx=5, pady=5)
>
> > > self.btnDisplay = Button(self, text="7", default=ACTIVE)
> > > self.btnDisplay.grid(row=5, column=0, padx=5, pady=5)
>
> > > self.btnDisplay = Button(self, text="8", default=ACTIVE)
> > > self.btnDisplay.grid(row=5, column=1, padx=5, pady=5)
>
> > > self.btnDisplay = Button(self, text="9", default=ACTIVE)
> > > self.btnDisplay.grid(row=5, column=2, padx=5, pady=5)
>
> > > self.btnDisplay = Button(self, text="*", default=ACTIVE)
> > > self.btnDisplay.grid(row=5, column=3, padx=5, pady=5)
>
> > > self.btnDisplay = Button(self, text="0", default=ACTIVE)
> > > self.btnDisplay.grid(row=6, column=0, padx=5, pady=5)
>
> > > self.btnDisplay = Button(self, text="C", default=ACTIVE)
> > > self.btnDisplay.grid(row=6, column=1, padx=5, pady=5)
>
> > > self.btnDisplay = Button(self, text="r", default=ACTIVE)
> > > self.btnDisplay.grid(row=6, column=2, padx=5, pady=5)
>
> > > self.btnDisplay = Button(self, text="/", default=ACTIVE)
> > > self.btnDisplay.grid(row=6, column=3, padx=5, pady=5)
>
> > > def Display(self, xbtn):
> > > if xbtn==1:
> > > print 1
>
> > > if __name__ == "__main__":
> > > guiFrame = GUIFramework()
> > > guiFrame.mainloop()
>
> > > [/code]
>
> > If you have this function:
>
> > def f():
> > print 1
> > return 10
>
> > and you write:
>
> > result = f()
>
> > The '()' is the function execution operator; it tells python to
> > execute the function. In this case, the function executes, and then
> > the return value of the function is assigned to the variable result.
> > If a function does not have a return statement, then the function
> > returns None by default.
>
> > The same thing is happening in this portion of your code:
>
> > command = self.Display(1)
>
> > That code tells python to execute the Display function and assign the
> > function's return value to the variable command. As a result Display
> > executes and 1 is displayed. Then since Dispay does not have a return
> > statement, None is returned, and None is assigned to command.
> > Obviously, that is not what you want to do.
>
> > What you want to do is assign a "function reference" to command so
> > that python can execute the function sometime later when you click on
> > the button. A function reference is just the function name without
> > the '()' after it. So you would write:
>
> > command = self.Display
>
> > But writing it like that doesn't allow *you* to pass any arguments to
> > Display(). In addition, *tkinter* does not pass any arguments to
> > Display when tkinter calls Display in response to a button click. As
> > a result, there is no way to pass an argument to Display.
>
> > However, there is another way to cause a function to execute when an
> > event, like a button click, occurs on a widget: you use the widget's
> > bind() function:
>
> > my_button.bind('<Button-1>', someFunc)
>
> > The first argument tells tkinter what event to respond to.
> > '<Button-1>' is a left click. Check the docs for the different
> > strings that represent the different events that you can respond to.
> > The second argument is a function reference, which once again does not
> > allow you to pass any arguments to the function. However, when you
> > use bind() to attach a function to a widget, tkinter calls the
> > function and passes it one argument: the "event object". The event
> > object contains various pieces of information, and one piece of
> > information it contains is the widget upon which the event occurred,
> > e.g. the button that was clicked. To get the button, you write:
>
> > Display(self, event_obj):
> > button = event_obj.widget
>
> > Once you have the button, you can get the text on the button:
>
> > Display(self, event_obj):
> > button = event_obj.widget
> > text = button.cget("text")
>
> > if text=="1":
> > print 1
>
> > Another thing you should be aware of: self is like a class wide
> > bulletin board. If you are writing code inside a class method, and
> > there is data that you want code inside another class method to be
> > able to see, then post the data on the class wide bulletin board, i.e.
> > attach it to self. But in your code, you are doing this:
>
> > self.btnDisplay = Button(self, text="7", default=ACTIVE)
> > self.btnDisplay.grid(row=5, column=0, padx=5, pady=5)
>
> > self.btnDisplay = Button(self, text="8", default=ACTIVE)
> > self.btnDisplay.grid(row=5, column=1, padx=5, pady=5)
>
> > As a result, your code continually overwrites self.btnDisplay. That
> > means you aren't preserving the data assigned to self.btnDisplay.
> > Therefore, the data does not need to be posted on the class wide
> > bulletin board for other class methods to see. So just write:
>
> > btnDisplay = Button(self, text="7", default=ACTIVE)
> > btnDisplay.grid(row=5, column=0, padx=5, pady=5)
>
> > btnDisplay = Button(self, text="8", default=ACTIVE)
> > btnDisplay.grid(row=5, column=1, padx=5, pady=5)
>
> > As for the button sizing problem, your buttons are all the same size
> > and line up perfectly on mac os x 10.4.7.
>
> wow thank you so much, awesome answer i will get right to fixing this
> now.
>
> in regards to the buttonsizes i use windows VISTA and they have
> different sizes.
one thing i dont rally get, i ahve to add my_button.bind() somewhere?
i changed the stuff u said though and i get this error(the program
executes though and i can press the buttons):
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python25\lib\lib-tk\Tkinter.py", line 1403, in __call__
return self.func(*args)
TypeError: Display() takes exactly 2 arguments (1 given)
current version:
#! /usr/bin/env python
from Tkinter import *
import tkMessageBox
class GUIFramework(Frame):
"""This is the GUI"""
def __init__(self,master=None):
"""Initialize yourself"""
"""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):
enText = Entry(self)
enText.grid(row=0, column=0, columnspan=8, padx=5, pady=5)
enText = Entry(self)
enText.grid(row=1, column=0, columnspan=8, padx=5, pady=5)
btnDisplay = Button(self, text="1", command=self.Display)
btnDisplay.grid(row=3, column=0, padx=5, pady=5)
btnDisplay = Button(self, text="2", default=ACTIVE)
btnDisplay.grid(row=3, column=1, padx=5, pady=5)
btnDisplay = Button(self, text="3", default=ACTIVE)
btnDisplay.grid(row=3, column=2, padx=5, pady=5)
btnDisplay = Button(self, text="+", default=ACTIVE)
btnDisplay.grid(row=3, column=3, padx=5, pady=5)
btnDisplay = Button(self, text="4", default=ACTIVE)
btnDisplay.grid(row=4, column=0, padx=5, pady=5)
self.btnDisplay = Button(self, text="5", default=ACTIVE)
self.btnDisplay.grid(row=4, column=1, padx=5, pady=5)
btnDisplay = Button(self, text="6", default=ACTIVE)
btnDisplay.grid(row=4, column=2, padx=5, pady=5)
btnDisplay = Button(self, text="-", default=ACTIVE)
btnDisplay.grid(row=4, column=3, padx=5, pady=5)
btnDisplay = Button(self, text="7", default=ACTIVE)
btnDisplay.grid(row=5, column=0, padx=5, pady=5)
btnDisplay = Button(self, text="8", default=ACTIVE)
btnDisplay.grid(row=5, column=1, padx=5, pady=5)
btnDisplay = Button(self, text="9", default=ACTIVE)
btnDisplay.grid(row=5, column=2, padx=5, pady=5)
btnDisplay = Button(self, text="*", default=ACTIVE)
btnDisplay.grid(row=5, column=3, padx=5, pady=5)
btnDisplay = Button(self, text="0", default=ACTIVE)
btnDisplay.grid(row=6, column=0, padx=5, pady=5)
btnDisplay = Button(self, text="C", default=ACTIVE)
btnDisplay.grid(row=6, column=1, padx=5, pady=5)
btnDisplay = Button(self, text="r", default=ACTIVE)
btnDisplay.grid(row=6, column=2, padx=5, pady=5)
btnDisplay = Button(self, text="/", default=ACTIVE)
btnDisplay.grid(row=6, column=3, padx=5, pady=5)
#self.btnDisplay(expand=0/1)
## def Display(self, xbtn):
## if xbtn==1:
## print 1
def Display(self, event_obj):
button = event_obj.widget
text = button.cget("text")
if text=="1":
print 1
if __name__ == "__main__":
guiFrame = GUIFramework()
guiFrame.mainloop()
More information about the Python-list
mailing list