TKinter, buttonwidget response problem(1) and all btns the same size(2)!

skanemupp at yahoo.se skanemupp at yahoo.se
Sat Apr 5 07:05:35 CEST 2008


On 5 Apr, 07:02, skanem... at yahoo.se wrote:
> 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,...
>
> läs mer »


and the self. i erased, should i do it in the def __init__ as well or
only as i did in createwidgets-function?



More information about the Python-list mailing list