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

skanemupp at yahoo.se skanemupp at yahoo.se
Fri Apr 4 23:57:58 EDT 2008


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.



More information about the Python-list mailing list