0

So I have the code here:

import tkinter as tk

def add_x(x,y):
    return y + x
    
     
class creator():
    
    def __init__(self,val):
        self.val = val
        self.root = tk.Tk()

    def func(self,cmd,amount):
        change_val = cmd(self.val,amount)
        self.val = change_val
        return self.val

    def btn(self,cmd):        
        btn_text = tk.StringVar()
        def update_btn_text(var):
            btn_text.set(var)
        btn = tk.Button(self.root, textvariable=btn_text,
                        command = update_btn_text(cmd))
        btn_text.set(0)
        btn.pack()

    def run(self):
        self.root.mainloop()

a = creator(0)
a.btn(a.func(add_x,1))

What this is supposed to do is create a button that will increase the displayed text by one each time it is pressed. The issue is that when I try running it, nothing will happen and it will only change a.val to 1 at the beginning and keep the button text at 0. Does anyone know why this is happening? Thanks! This got closed because it was associated with another question, but nothing there answered my question. Using lambda breaks my code and partial does nothing.

  • No, I already found that and I couldn't get anything there to work. When I attempt to use lambda it can only run once, when I want to run multiple times and using partial doesn't fix it either. – Zeke Bennett Jan 23 '22 at 01:35
  • 1
    When you do `a.btn(a.func(add_x,1))` that calls `a.func` immediately. It will change the btn's text to 1, and then return 1, and that's what you pass to `a.btn`. – Tim Roberts Jan 23 '22 at 01:46
  • Is there any way to stop that? I've tried using lambda with it but it doesn't work; it just keeps the display at zero and doesn't print anything when I press the button. – Zeke Bennett Jan 23 '22 at 01:49

1 Answers1

0

This works. What you pass to btn has to be a lambda, and what you pass to tk.Button has to be a lambda. I can't help but think this is over-engineered. There are far simpler ways to get an incrementing button.

import tkinter as tk

def add_x(x,y):
    return y + x
    
     
class creator():
    
    def __init__(self,val):
        self.val = val
        self.root = tk.Tk()

    def func(self,cmd,amount):
        change_val = cmd(self.val,amount)
        print('cv',change_val)
        self.val = change_val
        return self.val

    def btn(self,cmd):        
        btn_text = tk.StringVar()
        def update_btn_text(var):
            btn_text.set(var())
        btn = tk.Button(self.root, textvariable=btn_text,
                        command = lambda : update_btn_text(cmd))
        btn_text.set(0)
        btn.pack()

    def run(self):
        self.root.mainloop()

a = creator(0)
a.btn(lambda : a.func(add_x,1))
a.run()
Tim Roberts
  • 48,973
  • 4
  • 21
  • 30
  • I had tried doing that earlier, but whenever lambda is passed in the second to last line, it just causes the display to change to " at 0x000001FE773EE9D0>". You did say that there were easier ways to do this though, would you be able to give a quick example of one if that is easier? Thanks! – Zeke Bennett Jan 23 '22 at 01:55
  • I can tell you, I ran that exact code before I posted it, and it works. The button increments. The problem we have is, we don't know what you're real plan is. If you just want a button that increments, that doesn't require two functions and two lambdas, but based on your choices, I'm guessing there's more to your concept. – Tim Roberts Jan 23 '22 at 06:01
  • Ah I just missed the parentheses after var, it does work now. And yes, I'm planning on adding a bunch of different functions so it doesn't just increment. Thanks! – Zeke Bennett Jan 23 '22 at 16:26