Python Forum
Passing arguments into function, tkinter
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Passing arguments into function, tkinter
Hey folks,
I've got a very limited understanding of how to pass information through a function. I have a tkinter page with multiple buttons. (Just FYI I copied code from various google searches to make this work so I'm not even sure what **kwargs is doing for my purpose but I don't care at the moment that is not my question)

In this format I am curious how to give each button it's own text. I attempted using the variable 'button_label' but not sure how to pass this information into the class.

I also have an argument called 'which_button' and 'btnGPIO' which pass the information of which GPIO pin to toggle, but again not sure how to pass this info through the clicked function.

I'm sure this is fairly basic stuff but I cannot find a solution to either yet... any help is appreciated!!

from tkinter import *
import raspberryGPIO

functionsPage = Tk()

class Toggle(Frame):
    def __init__(self, master=None, **kwargs):
        Frame.__init__(self, master, **kwargs)

        self.btn = Button(self, text=button_label, width=20, height=5, bg="yellow", command=self.clicked(which_button=btnGPIO)) 
        self.btn.grid(column=0, row=0, pady=10)

    def clicked(self, which_button):
        if self.btn['bg'] == "yellow":
            GPIO.output(which_button, GPIO.LOW)
            GPIO.output(which_button, GPIO.HIGH)

btn1 = Toggle(functionsPage)
btn2 = Toggle(functionsPage)

Pass attributes into the __init__, attributes used in methods of the class assign as class attributes

import tkinter as tk
import raspberryGPIO

functionsPage = tk.Tk()

class Toggle(tk.Frame):
    def __init__(self, button_label, which_button, master=None, **kwargs):
        tk.Frame.__init__(self, master, **kwargs)
        self.which_button = which_button

        self.btn = tk.Button(self, text=button_label, width=20,
                             height=5, bg="yellow", command=self.clicked)
        self.btn.grid(column=0, row=0, pady=10)

    def clicked(self):
        if self.btn['bg'] == "yellow":
            GPIO.output(self.which_button, GPIO.LOW)
            GPIO.output(self.which_button, GPIO.HIGH)

which_button1 = 'Asign this'
which_button2 = 'Asign this'

btn1 = Toggle('button_label1', which_button1, functionsPage)
btn2 = Toggle('button_label2', which_button2, functionsPage)

There are two kinds of arguments in Python, Positional args and keyword args. Positional args look like this:
def funcA(a, b, c)
    return a+b/c
sum = funcA(1, 2, 3)
If I call funcA I need to provide 3 values. The first is for "a", the second for "b", and the third for "c". The mapping between the arguments in the function and the values in the function call is passed on their Position.

Python also allows using the argument name when calling a function. I could also call funcA like this:
sum = func(a = 1, c = 3, b = 2)
This gives the same result as before, even though the values are in a different order. When passing arguments like this Python uses the variable name as a key word. These are called keyword arguments.

Sometimes you want a function that can accept a variable number of arguments. If I want a more flexible version of funcA where I can provide 2 or 4 or N numbers and a divisor I could write it like this:
def funcA(*args, divisor=1):
    return sum(args) / divisor

value = funcA(1, 2, divisor=3)
value2 = funcA(1, 2, a=3, divisor=3) # Error! Only keyword arg allowed is divisor
In funcA, *args takes the place of all the positional arguments. I could sum two numbers or ten numbers. I could write this function to sum the first N-1 numbers and divide by the last, but I think it is easier to understand the function if the special divisor argument is always a keyword argument.

You can also write functions that take a variable number of position arguments and a variable number of keyword arguments, such as the __init__ method in your Toggle class. **kwargs is a tuple of key/value arguments. The kwargs name is convention only, you could name it anything you want. The important part is the "**". So in function arguments "*" means position arguments and "**" are keyword arguments.

Passing through arguments to your super class allows you not only pass arguments to be used by your class, but to pass arguments to your class's super. For example, using the Toggle class from Yoriz I could type:
button = Toggle('button_label1', which_button1, functionsPage, height=2, width=3)
The Toggle __init__ does not have "height" or "width" arguments, so these are part of the **kwargs list. When you call:
tk.Frame.__init__(self, master, **kwargs)
these arguments are passed along to tk.Frame.__init__ which does know what to do with height and width.
Yes thanks for both of your answers! Very helpful!

Possibly Related Threads…
Thread Author Replies Views Last Post
  [Tkinter] Passing information with a function Krisve94 3 222 Jun-30-2021, 07:51 PM
Last Post: deanhystad
  [Tkinter] Passing variable to function. KDog 2 322 May-25-2021, 09:15 PM
Last Post: KDog
  tkinter get function finndude 2 555 Mar-02-2021, 03:53 PM
Last Post: finndude
  tkinter -- after() method and return from function -- (python 3) Nick_tkinter 12 1,011 Feb-20-2021, 10:26 PM
Last Post: Nick_tkinter
  Using Tkinter inside function not working Ensaimadeta 3 714 Dec-23-2020, 02:57 PM
Last Post: deanhystad
  function in new window (tkinter) Dale22 7 890 Nov-24-2020, 11:28 PM
Last Post: Dale22
Star [Tkinter] How to perform math function in different page of Tkinter GUI ravaru 2 957 Oct-23-2020, 05:46 PM
Last Post: deanhystad
  Call local variable of previous function from another function with Python3 & tkinter Hannibal 5 1,005 Oct-12-2020, 09:16 PM
Last Post: deanhystad
  tkinter get method is not accepting value when called by function jagasrik 1 616 Sep-16-2020, 05:28 AM
Last Post: Yoriz
  [Tkinter] Use function from other class (Tkinter) zarize 8 1,242 Aug-17-2020, 09:47 AM
Last Post: zarize

Forum Jump:

User Panel Messages

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