2

How would I run an if statement to determine which button was clicked? I've been looking around, but I am new to Tkinter and I'm not too sure what I'm supposed to do.

    self.button1 = Tkinter.Button(self,text=u"Convert Decimal to Binary", command=self.OnButtonClick)
    self.button1.grid(column=1,row=1)

    self.button2 = Tkinter.Button(self,text=u"Convert Binary to Decimal", command=self.OnButtonClick)
    self.button2.grid(column=1,row=2)
Dan
  • 37
  • 1
  • 1
  • 5

5 Answers5

9

You could set each button's command option to a lambda like this:

self.button1 = Tkinter.Button(self, ..., command=lambda: self.OnButtonClick(1))
...
self.button2 = Tkinter.Button(self, ..., command=lambda: self.OnButtonClick(2))

Then, make self.OnButtonClick accept an argument that will be the button's "id". It would be something like this:

def OnButtonClick(self, button_id):
    if button_id == 1:
        # self.button1 was clicked; do something
    elif button_id == 2:
        # self.button2 was clicked; do something
  • I ran the program after switching those lines, but I am receiving an attribute error with the OnButtonClick function. – Dan Jan 15 '14 at 21:42
  • @Dan - That sounds like a separate issue. Could we see the traceback and relevant code? –  Jan 15 '14 at 21:47
  • Just noticed that I copied and pasted a line and forgot the indentation, which caused that error. My apologies for not noticing that before I posted that comment. – Dan Jan 16 '14 at 01:55
  • Just one last question. After I determine which button was pressed, I have a text box above the original two buttons for the number that is being converted to be typed. Below it, I want to delete the previous two buttons were there, and instead have one button there for the user to click on to convert the number. How would I do this? – Dan Jan 16 '14 at 02:19
  • @Dan - This link will show you how to remove the buttons from view: http://stackoverflow.com/a/12365098/2555451 –  Jan 16 '14 at 02:33
5

An object-oriented way to do this is to just pass the button clicked to theOnButtonClick()method:

    def OnButtonClick(self, button):
        # do stuff with button passed...
        ...

In order to do this requires creating and configuring each button in two steps. That's necessary because you need to pass the button as an argument to the command which can't be done in the same statement that creates the button itself:

    button1 = Tkinter.Button(self, text=u"Convert Decimal to Binary")
    button1.config(command=lambda button=button1: self.OnButtonClick(button))
    button2 = Tkinter.Button(self, text=u"Convert Binary to Decimal")
    button2.config(command=lambda button=button2: self.OnButtonClick(button))
martineau
  • 119,623
  • 25
  • 170
  • 301
2

Tkinter does not pass any parameter to the callbacks - so, you have to pass a different callable object to each button.

The good news is that you don't need to implement as many functions as there are buttons: you can create short anonymous functions that just add informationa bout which button was clicked to the real callback. These anonymous functions, created with the lambda keyword can be created when connecting the buttons by filling in the command option:

self.button1 = Tkinter.Button(self,text=u"Convert Decimal to Binary", command=lambda: self.OnButtonClick("b1") )
self.button1.grid(column=1,row=1)

self.button2 = Tkinter.Button(self,text=u"Convert Binary to Decimal", command=lambda: self.OnButtonClick("b2") )
self.button2.grid(column=1,row=2)

This way, the OnButtonCLick method will have the strings "b1" and "b2" respectively as the second parameter on the call (the first parameter will be the reference to the object itself - self )

If you want to pass a reference to the buttons themselves, you have to configure their command in a subsequent line, after they've been created:

self.button1 = Tkinter.Button(self,text=u"Convert Decimal to Binary")
self.button1["command"] = lambda: self.OnButtonClick(self.button1) 
...
jsbueno
  • 99,910
  • 10
  • 151
  • 209
1

Use a different callback for each button.

button1 = Tkinter.Button(self, ..., command=self.OnButton1Click)
button2 = Tkinter.Button(self, ..., command=self.OnButton2Click)
nandhp
  • 4,680
  • 2
  • 30
  • 42
  • This solves the problem but it's highly inconvenient when `OnButton1Click` and `OnButton2Click` are supposed to be the same function. – Javier Jan 28 '19 at 13:52
1

Don't use Button's because you cannot access the Label text displayed on the Button. This is because legacy tcl implementation of the button does not include access to the text label on the button which was used to implement Tkinter which was used to implement ttl. You also cannot set the widgetname in the constructor, so at best you get a unique hex value of the button object._name.

Use an Entry where you can set and get the string in the text field with a local method from Object

Entry.get() # Returns text from Entry object
Entry.insert(0, "text") # Inserts text at index 0, or the beginning

New convention using bind

You can bind any ttk object with bind

Entry.bind("<Button-1>",self.mouseClickinEntry)

def mouseClickinEntry(self,event)
    print(event.widget.get()) # Where widget is the Entry Object from click event

So when you click in the Entry text area, mouseClickinEntry will execute and you will get "text" exactly how it appears when you inserted it. Now you know which Entry you clicked in.