Building desktop applications in Python is one of my favorite ways to solve everyday problems. Whether it’s a simple calculator or a complex data dashboard, buttons are the heart of the user interface.
I’ve spent years developing Tkinter applications, and I can tell you that understanding the command attribute is the most important step in making your app interactive.
In this tutorial, I will show you exactly how the Tkinter Button command works through practical, real-world examples that go way beyond a simple “Hello World.”
How the Tkinter Button Command Works
When you create a button in Tkinter, it stays idle until a user clicks it. The command attribute is what tells Python which function to run when that click happens.
I often think of it as a doorbell; the button is the physical switch, and the command is the chime that rings inside the house.
The Basic Syntax
The syntax for a basic button is simple. You define a function first, then reference it inside the button widget.
import tkinter as tk
def my_function():
print("Action triggered!")
root = tk.Tk()
btn = tk.Button(root, text="Click Me", command=my_function)
btn.pack()
root.mainloop()One mistake I see beginners make constantly is adding parentheses to the function name inside the command attribute (e.g., command=my_function()).
If you do that, the function runs immediately when the app starts, not when the button is clicked. Always pass the function name without parentheses.
Method 1: Use the Command for Simple Actions
Let’s look at a practical example. Imagine you are building a tool for a retail office in Chicago to calculate sales tax quickly.
In this scenario, we want a button that takes a subtotal and displays the final price, including the local tax rate.
import tkinter as tk
# Experienced developer tip: Always use a main class for larger apps
class TaxCalculator:
def __init__(self, root):
self.root = root
self.root.title("Chicago Sales Tax Tool")
self.root.geometry("400x250")
# Input label and entry
self.label = tk.Label(root, text="Enter Order Subtotal ($):")
self.label.pack(pady=10)
self.amount_entry = tk.Entry(root)
self.amount_entry.pack(pady=5)
# The Button with the command
# Notice I am calling self.calculate_tax without ()
self.calc_btn = tk.Button(
root,
text="Calculate Total",
command=self.calculate_tax,
bg="#0078d4",
fg="white"
)
self.calc_btn.pack(pady=20)
self.result_label = tk.Label(root, text="", font=("Arial", 12, "bold"))
self.result_label.pack(pady=10)
def calculate_tax(self):
try:
subtotal = float(self.amount_entry.get())
# Chicago sales tax is approximately 10.25%
total = subtotal * 1.1025
self.result_label.config(text=f"Total with Tax: ${total:.2f}")
except ValueError:
self.result_label.config(text="Please enter a valid number", fg="red")
if __name__ == "__main__":
window = tk.Tk()
app = TaxCalculator(window)
window.mainloop()You can refer to the screenshot below to see the output.

In this example, the command=self.calculate_tax line links the button to the logic. It’s clean, readable, and works perfectly for standard triggers.
Method 2: Pass Arguments Using Lambda Functions
There are many times in my career when I needed a single function to handle multiple buttons. For instance, imagine a temperature monitoring system for a warehouse in Seattle.
If you have buttons for “Office,” “Storage,” and “Loading Dock,” you don’t want three separate functions. You want one function that knows which button was pressed.
Since the command attribute doesn’t allow parentheses, we use a lambda function as a “wrapper.”
Real-World Example: Warehouse Temperature Toggle
import tkinter as tk
def update_status(location, temp):
status_label.config(text=f"Current Temp in {location}: {temp}°F")
root = tk.Tk()
root.title("Seattle Logistics Hub - Temp Monitor")
root.geometry("450x300")
tk.Label(root, text="Select Zone to Check Temperature:", font=("Arial", 10)).pack(pady=15)
# Using Lambda to pass specific data to the same function
btn_office = tk.Button(
root,
text="Check Office",
command=lambda: update_status("Main Office", 72)
)
btn_office.pack(pady=5)
btn_storage = tk.Button(
root,
text="Check Cold Storage",
command=lambda: update_status("Cold Storage", 34)
)
btn_storage.pack(pady=5)
btn_dock = tk.Button(
root,
text="Check Loading Dock",
command=lambda: update_status("Loading Dock", 55)
)
btn_dock.pack(pady=5)
status_label = tk.Label(root, text="Select a zone...", fg="blue", font=("Arial", 12))
status_label.pack(pady=20)
root.mainloop()You can refer to the screenshot below to see the output.

Using lambda is a pro move. It allows you to pass variables into your commands dynamically, keeping your code “DRY” (Don’t Repeat Yourself).
Method 3: Use functools.partial for Cleaner Code
While lambda is popular, I personally prefer functools.partial when working on professional-grade software.
It is often more readable and avoids some common scoping issues that lambdas can run into when used inside loops.
Example: US Currency Converter
Let’s build a small utility that converts USD to other currencies using partial.
import tkinter as tk
from functools import partial
def convert_currency(rate, name):
try:
usd_amount = float(entry.get())
converted = usd_amount * rate
result_label.config(text=f"{usd_amount} USD = {converted:.2f} {name}")
except ValueError:
result_label.config(text="Enter valid USD amount")
root = tk.Tk()
root.title("Global Trade Converter")
tk.Label(root, text="Amount in USD:").pack(pady=5)
entry = tk.Entry(root)
entry.pack(pady=5)
# Defining partial functions
to_euro = partial(convert_currency, 0.92, "EUR")
to_gbp = partial(convert_currency, 0.79, "GBP")
to_cad = partial(convert_currency, 1.35, "CAD")
tk.Button(root, text="Convert to EUR", command=to_euro).pack(pady=2)
tk.Button(root, text="Convert to GBP", command=to_gbp).pack(pady=2)
tk.Button(root, text="Convert to CAD", command=to_cad).pack(pady=2)
result_label = tk.Label(root, text="")
result_label.pack(pady=10)
root.mainloop()You can refer to the screenshot below to see the output.

I find partial to be much more explicit. It clearly states what function is being called and what arguments are being “pre-filled.”
Method 4: Handle Dynamic Button States
In sophisticated UI design, a button’s command might need to change based on the application’s state.
I’ve used this frequently in “Submit” forms, where the button first validates data and, once validated, changes its command to “Send.”
You can use the .config() method to update the command attribute while the app is running.
Example: Multi-step Enrollment Form
import tkinter as tk
def start_process():
info_label.config(text="Step 1: Validating ID...")
# Change the button command dynamically
action_btn.config(text="Confirm Enrollment", command=finish_process, bg="green")
def finish_process():
info_label.config(text="Enrollment Complete! Welcome to the Program.")
action_btn.config(state="disabled")
root = tk.Tk()
root.title("NYC Training Portal")
root.geometry("350x200")
info_label = tk.Label(root, text="Ready to begin?", wraplength=300)
info_label.pack(pady=20)
action_btn = tk.Button(root, text="Start Application", command=start_process)
action_btn.pack(pady=10)
root.mainloop()This approach creates a much more fluid user experience because the interface guides the user through the workflow
Troubleshoot Common Issues
If your button isn’t working as expected, check these three things first. I’ve lost count of how many times these were the culprits in my projects.
The function runs on startup: You likely wrote command=my_func(). Remove the ().
Nothing happens when clicked: Ensure you haven’t overwritten the function name somewhere else in your code. Also, check if the button is actually being “packed” or “placed” on the screen.
Variable scope issues in loops: If you create buttons in a loop and use a lambda, all buttons might end up using the last value of the loop. Use lambda x=val: func(x) to “capture” the current value.
I hope this guide helps you build more interactive and professional Python applications. Understanding how to control button actions is a huge step in your development journey.
Tkinter is a powerful tool once you master these small nuances. If you have any questions or run into specific issues with your commands, feel free to reach out.
You may also like to read:
- How to Change Tkinter Frame Background Color
- How to Update Tkinter Label Text Dynamically
- Tkinter Get Mouse Position
- How to Get Text from a Tkinter Entry Widget

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.