Python Forum
Buttons don't work
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Buttons don't work
#1
I wrote the following program because I am trying to understand TKinter and classes.

I want the code to print "blue square" when I click the blue button. I want it to print "red circle" when I press the red button.

The buttons don't seem to do anything.

The program does print "blue square" and "red circle" and I don't understand why.

Why does the program print "blue square" and "red circle"? Why don't the buttons worK?

import tkinter as tk

root = tk.Tk()
# from tkinter import ttk
myfont = "helvitica 25"
mybg = "light sky blue"
myheight = 4
mywidth = 60
myheight2 = 6
mywidth2 = 20
myheight3 = 3
mywidth3 = 20
labcol = "spring green"
anscol = "yellow"
otherbutcol = "skyblue"
commandbutcol = "light sky blue"
mypadx =0
mypady=0

class mymenu:

    def __init__(self, root):
        self.root = root
        root.geometry('1200x1200')
        self.mainmenu()

    def mainmenu(self):
        self.mmframe = tk.Frame(root)
        self.mmframe.grid(row=0, column=0, sticky=tk.W + tk.E, padx=mypadx, pady=mypady)

        self.mb = tk.Button(self.mmframe, text="mybutton", bg=commandbutcol, font=myfont, relief="groove", command = colshape("bs"))
        self.mb.config(height=myheight3, width=mywidth2)
        self.mb.grid(row=2, column=1, sticky=tk.W + tk.E, padx=mypadx, pady=mypady)

        self.mob = tk.Button(self.mmframe, text="myotherbutton", bg="red", font=myfont, relief="groove", command =colshape("rc"))
        self.mob.config(height=myheight3, width=mywidth2)
        self.mob.grid(row=2, column=2, sticky=tk.W + tk.E, padx=mypadx, pady=mypady)

def colshape(colshape):
    color = colshape[0]
    shape = colshape[1]

    if color == "r":
        color = "red"

    else:
        color = "blue"

    if shape == "s":
        shape = "square"

    else:
        shape = "circle"
    print(color, shape)

m = mymenu(root)
root.mainloop()
Reply
#2
There is no such thing as Combobutton in Tk. Do you meant ttk.Combobox? You aren't using one of those in your code. From the code it appears you are having a problem with Button. Plain old Button.

Your problem is you don't understand how the command=function works. When binding a callback to a button press, the myfunc in command=myfunc is a function, not a function call. colshape("rc") is a FUNCTION CALL. I calls the function coloshape() with the argument "rc" and sets command = the function return value. Which is None. So your code is really doing this:
self.mb = tk.Button(self.mmframe, text="mybutton", bg=commandbutcol, font=myfont, relief="groove", command = None)
You could try doing this:
self.mb = tk.Button(self.mmframe, text="mybutton", bg=commandbutcol, font=myfont, relief="groove", command = colshape)
This would call the colshape() function when you press the button, but it results in an error.
Error:
TypeError: colshape() missing 1 required positional argument: 'colshape'
How do you provide an argument for the function?

There are multiple ways this can be done. You could write a special function for each button so you don't need to pass an argument. You could use a partial function. Read about that in the functools library documentation. You could use a lambda expression.

https://docs.python.org/3/library/functools.html
https://docs.python.org/3/tutorial/contr...xpressions

For this particular problem, most of the code I've seen uses a lambda expression. A lambda expression is very much like writing a special function for the button, but it uses a more compact syntax. This is mainmenu() using lambda expressions.
    def mainmenu(self):
        self.mmframe = tk.Frame(root)
        self.mmframe.grid(row=0, column=0, sticky=tk.W + tk.E, padx=mypadx, pady=mypady)
 
        mb_pressed = lambda : colshape('bc')
        self.mb = tk.Button(self.mmframe, text="mybutton", bg=commandbutcol, \
                            font=myfont, relief="groove", command = mb_pressed)
        self.mb.config(height=myheight3, width=mywidth2)
        self.mb.grid(row=2, column=1, sticky=tk.W + tk.E, padx=mypadx, pady=mypady)

        mob_pressed = lambda : colshape('rs')
        self.mob = tk.Button(self.mmframe, text="myotherbutton", bg="red", \
                             font=myfont, relief="groove", command =mob_pressed)
        self.mob.config(height=myheight3, width=mywidth2)
        self.mob.grid(row=2, column=2, sticky=tk.W + tk.E, padx=mypadx, pady=mypady)
"mb_pressed = lambda : colshape('bc')" creates a function that calls colshape() with the argument 'bc'. It is the same as:
def mb_pressed():
    colshape('bc')
The code can be made even more compact by including the lambda expression in the Button() call.
    def mainmenu(self):
        self.mmframe = tk.Frame(root)
        self.mmframe.grid(row=0, column=0, sticky=tk.W + tk.E, padx=mypadx, pady=mypady)
 
        self.mb = tk.Button(self.mmframe, text="mybutton", bg=commandbutcol,  font=myfont, \
                            relief="groove", command=lambda : colshape('bc'))
        self.mb.config(height=myheight3, width=mywidth2)
        self.mb.grid(row=2, column=1, sticky=tk.W + tk.E, padx=mypadx, pady=mypady)

        self.mob = tk.Button(self.mmframe, text="myotherbutton", bg="red", font=myfont, \
                             relief="groove", command=lambda : colshape('rs'))
        self.mob.config(height=myheight3, width=mywidth2)
        self.mob.grid(row=2, column=2, sticky=tk.W + tk.E, padx=mypadx, pady=mypady)
 
Reply
#3
Thank you. I changed the title of my thread based on your comments.

The lambda seems like it will do exactly what I was trying to do.

It is a little confusing though because the lamda seems to have the exact same code I had, except in a lambda.
Reply
#4
Maybe you should read about lambda expressions. Then you would understand the difference. Like I said, the lambda expression makes a new function. In my example it is a function without any arguments that calls colshape("bc")
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [Tkinter] How do you create buttons and what is or how does super work? Fox_cutter12 2 2,992 May-10-2018, 08:14 PM
Last Post: notreallyapro

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020