Marc43
Marc43

Reputation: 491

Change the value of a variable with a button (Tkinter)

I want to change the value of a variable just with a button, i don't want to create a new entire function just like that:

from Tkinter import *
variable = 1
def makeSomething():
    global variable
    variable = 2
root = Tk()
myButton = Button(root, text='Press me',command=makeSomething).pack()

How i can do that? (I need to do that for six buttons, making six functions it's not an option)

Upvotes: 3

Views: 53410

Answers (3)

Kevin
Kevin

Reputation: 76184

i need to make this for 6 buttons...

If each button modifies the same global variable, then have make_something accept a value parameter:

from tkinter import Tk, Button
variable = 1
def make_something(value):
    global variable
    variable = value
root = Tk()
Button(root, text='Set value to four',command=lambda *args: make_something(4)).pack()
Button(root, text='Set value to eight',command=lambda *args: make_something(8)).pack()
Button(root, text='Set value to fifteen',command=lambda *args: make_something(15)).pack()
#...etc

If each button modifies a different global, then condense all your globals into a single global dict, which make_something can then modify.

from tkinter import Tk, Button
settings = {"foo": 1, "bar": 1, "baz": 1}

def make_something(name):
    settings[name] = 2

root = Tk()
Button(root, text='Set foo',command=lambda *args: make_something("foo")).pack()
Button(root, text='Set bar',command=lambda *args: make_something("bar")).pack()
Button(root, text='Set baz',command=lambda *args: make_something("baz")).pack()
#...etc

In either case, you still only require one function.


If lambdas aren't to your taste, you could use nested functions to create separate callables for each command:

from tkinter import Tk, Button
settings = {"foo": 1, "bar": 1, "baz": 1}

def make_callback(key):
    def make_something(*args):
        settings[key] = 2
    return make_something

root = Tk()
Button(root, text='Set foo',command=make_callback("foo")).pack()
Button(root, text='Set bar',command=make_callback("bar")).pack()
Button(root, text='Set baz',command=make_callback("baz")).pack()
#...etc

... And you can avoid globals by instead using attributes of a class instance:

from tkinter import Tk, Button

class GUI:
    def __init__(self):
        self.settings = {"foo": 1, "bar": 1, "baz": 1}
        self.root = Tk()
        Button(self.root, text='Set foo',command=self.make_callback("foo")).pack()
        Button(self.root, text='Set bar',command=self.make_callback("bar")).pack()
        Button(self.root, text='Set baz',command=self.make_callback("baz")).pack()
        #...etc

    def make_callback(self, key):
        def make_something(*args):
            self.settings[key] = 2
        return make_something

gui = GUI()

By the way, don't do this:

myButton = Button(root).pack()

This assigns the result of pack() to myButton, so myButton will be None instead of referring to your button. Instead, do:

myButton = Button(root)
myButton.pack()

Upvotes: 9

R3GUL4R
R3GUL4R

Reputation: 13

i'm a beginner but i think you should give the function 2 parameters one for the variable name and one for it value like this

def makeSomething(variableName,variableValue)
    variableName = variableValue

but as i said i'm a beginner so i could be wrong

Upvotes: 0

Deltix
Deltix

Reputation: 35

Update : I have it working (almost) fine This code works but I'd like to display in real time And when I uncoment the 2 things it doesn't do anything anymore

def BotPlay_Button():
    nPlay = entryN.get()
    jlist = [Joueur(File1,True,File1),Joueur(File2,True,File1)]
    Partie = Partie_Object(jlist)
    for i in range(int(nPlay)):
        Play_Partie(Partie)
        xList.append(i)
        y1List.append(bot1.score)
        y2List.append(bot2.score)
        # windo.update_idletasks()
        # windo.update()

Upvotes: 0

Related Questions