[Python / Tkinter] How to pass arguments to command

What to introduce this time

Options such as Button widget in Tkinter: I will show you how to pass arguments to communad.

Sample code (success example)

import tkinter as tk
import tkinter.ttk as ttk

class Application(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.master = master
        self.pack()
        self.master.title("Title")
        self.master.geometry("400x300")
        self.create_widgets()
    
    def create_widgets(self):
        for i in range(1, 11):
            ttk.Button(self, text=f"button{i}", command=self.show_message(i)).pack()
    
    def show_message(self, index):
        def inner():
            print(f"button{index}Was clicked")
        return inner

def main():
    root = tk.Tk()
    app = Application(master=root)
    app.mainloop()

if __name__ == "__main__":
    main()

Common mistakes and solutions

Why it fails

When I try to write it normally, I tend to write it as follows:


import tkinter as tk
import tkinter.ttk as ttk

class Application(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.master = master
        self.pack()
        self.master.title("Title")
        self.master.geometry("400x300")
        self.create_widgets()
    
    def create_widgets(self):
        for i in range(1, 11):
            ttk.Button(self, text=f"button{i}", command=self.show_message(i)).pack()
    
    def show_message(self, index):
        print(f"button{index}Was clicked")

def main():
    root = tk.Tk()
    app = Application(master=root)
    app.mainloop()

if __name__ == "__main__":
    main()

Unfortunately, this does not work as expected.

As you can see by moving it, self.show_message (i) is executed when the button is generated, and all buttons {index} are clicked are printed. And when the important button is clicked, no action is taken. This is related to the behavior of the command option as follows.

-** When widget is generated : self.show_message (i) is executed - When the button is clicked **: self.show_message (i) () is executed

Solution

Due to the troublesome specifications described above, some ingenuity is required when defining the callback function. Do not execute the necessary part of the code (in this case, print (f" button {index} was clicked ") with self.show_message (i), and self You need to run it with .show_message (i) () .

To do this, use the ** Inner Function **. It is easy to understand if you think that it is as follows.


def show_message(index):
    def inner():
        print(f"button{index}Was clicked")
    return inner

command = show_message(1)
command()

The inner function (internal function) is defined in the show_message function, and it is returned. In other words, the command on the second line from the bottom contains the inner function. However, since the contents of the inner function have not been executed, it will not be printed. And on the last line, we are executing the inner function.

In other words, show_message (1) does nothing in appearance, but show_message (1) () allows you to execute the desired part.

reference

--python tkinter How to determine which button was pressed --memorpy http://memopy.hatenadiary.jp/entry/2017/06/11/220452 --When passing arguments with Tkinter's command option, it works as expected to define nesting in the function https://qiita.com/yukid/items/a0140b5c1a3e28f636f0

Recommended Posts

[Python / Tkinter] How to pass arguments to command
How to receive command line arguments in Python
Let's understand how to pass arguments (Python version)
How to update Python Tkinter to 8.6
Execute Python function from Powershell (how to pass arguments)
[python] How to use __command__, function explanation
How to pass arguments to a Python script in SPSS Modeler Batch
How to pass arguments using an instance with systemd's systemctl command
How to install Python
How to install python
[Python] How to test command line parser click
How to implement Discord Slash Command in Python
How to use tkinter with python in pyenv
[Introduction to Udemy Python3 + Application] 67. Command line arguments
How to pass the execution result of a shell command in a list in Python
[2020.8 latest] How to install Python
[For beginners] How to use say command in python!
How to install Python [Windows]
python3: How to use bottle (2)
[Python] How to use list 1
Python: How to use pydub
[Python] How to use checkio
How to run Notepad ++ Python
How to manage arguments when implementing a Python script as a command line tool
How to change Python version
How to develop in Python
How to execute a command using subprocess in Python
[python] How to judge scalar
[Python] How to use input ()
How to rewrite Tkinter labels
How to use Python lambda
[Python] How to use virtualenv
python3: How to use bottle (3)
python3: How to use bottle
How to use Python bytes
How to run a Python file at a Windows 10 command prompt
How to specify command line arguments when debugging in PyCharm
How to write a Python class
[Python] How to FFT mp3 data
[Python] How to do PCA in Python
Python: How to use async with
[Python] How to derive nCk (ABC156-D)
[Python] How to use Pandas Series
How to collect images in Python
[Introduction to Python] How to parse JSON
In the python command python points to python3.8
How to use MBDyn (command setting)
How to get the Python version
How to get started with Python
[Python] How to import the library
How to use Mysql in python
How to use OpenPose's Python API
[Python] How to swap array values
How to wrap C in Python
How to use ChemSpider in Python
How to use FTP with Python
Python: How to use pydub (playback)
How to use PubChem in Python
How to speed up Python calculations
Pass arguments to Task in discord.py
How to calculate date with python