0

I am trying to make a class in python that lets you pass the executed onclick code through the constructor. So far:

import tkinter as tk
import PIL
from PIL import ImageTk, Image

class closeIcon:
  path = ""
  width = 0
  height = 0
  xpos = 0
  ypos = 0
  onclick = 0
  canv = ""

  def __init__(self, path, width, height, xpos, ypos, onclick, canv):
    self.path = path
    self.width = width
    self.height =  height
    self.xpos = xpos
    self.ypos = ypos
    self.onclick = onclick
    self.canv = canv
    self.img = Image.open(self.path).resize((self.width, self.height), Image.ANTIALIAS)
    self.img_ = ImageTk.PhotoImage(self.img)
    self.label = tk.Label(self.canv, image=self.img_, bg=self.canv["background"])
    self.label.place(x=xpos, y=ypos)
    self.label.bind("<Button-1>", self.onclick)

Example of how I would instanciate an object from that class:

closeAppIcon = closeIcon("assets/cross1.png", 30, 30, winWidth-45, 10, {print("Hello")}, canvas_)

But whenever I run the application I am getting an Hello in the console without even clicking on the image, and when I click on the image I get following error message:

Exception in Tkinter callback Traceback (most recent call last): File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.1776.0_x64__qbz5n2kfra8p0\lib\tkinter_init_.py", line 1883, in call return self.func(*args) TypeError: 'set' object is not callable

What am I doing wrong?

1
  • 2
    {print("Hello")} is a set containing the element None. Did you mean to pass a function? Commented Nov 1, 2020 at 9:50

1 Answer 1

4

{print("Hello")} is a set containing the element None. Your code expects a function in that place. If you want to pass a function containing the statement print("Hello"), you could use:

lambda *args: print("Hello")

This defines a function that will accept any number of positional arguments and print "Hello".

Sign up to request clarification or add additional context in comments.

4 Comments

Now Im getting the error "<lambda>() takes 0 positional arguments but 1 was given"
Try using lambda *args: instead of lambda:
lambda: indicates a function that receives no arguments. lambda *args: indicates a function that can receive any number of positional arguments. Evidently the particular callback here (onclick) requires a function that accepts one argument.
When you bind a function to an event, the function is always called with one argument, which is an object representing the event that triggered the callback.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.