CustomTkinter icon indicating copy to clipboard operation
CustomTkinter copied to clipboard

Canvas coords returns NoneType

Open dpacker780 opened this issue 2 years ago • 5 comments

Example:

self.crop_box = [0, 0, 100, 100]
self.crop_id = self.image_view.create_rectangle(self.crop_box, outline="#fff75e", tags="cropbox")
a, b, c, d = self.image_view.coords("cropbox")

Returns an error of NoneType, when coords is used to get the values of them from the item. Coords provides both set and get functionality.

Looking at the code, it looks like with the CTkCanvas implementation it overrides and calls the super, but without any return values.

dpacker780 avatar Jul 11 '23 21:07 dpacker780

A near-term fix can be simply added by placing 'return' statements in the ctk_canvas.py:

 def coords(self, tag_or_id, *args):

        if type(tag_or_id) == str and "ctk_aa_circle_font_element" in self.gettags(tag_or_id):
            coords_id = self.find_withtag(tag_or_id)[0]  # take the lowest id for the given tag
            return super().coords(coords_id, *args[:2])

            if len(args) == 3:
                super().itemconfigure(coords_id, font=("CustomTkinter_shapes_font", -int(args[2]) * 2), text=self._get_char_from_radius(args[2]))

        elif type(tag_or_id) == int and tag_or_id in self._aa_circle_canvas_ids:
            return super().coords(tag_or_id, *args[:2])

            if len(args) == 3:
                super().itemconfigure(tag_or_id, font=("CustomTkinter_shapes_font", -args[2] * 2), text=self._get_char_from_radius(args[2]))

        else:
            return super().coords(tag_or_id, *args)

dpacker780 avatar Jul 11 '23 21:07 dpacker780

Was able to replicate:

Traceback (most recent call last):
  File "/Users/dishb/Coding/test.py", line 24, in <module>
    app = App()
          ^^^^^
  File "/Users/dishb/Coding/test.py", line 11, in __init__
    self.canvas = TestCanvas(self)
                  ^^^^^^^^^^^^^^^^
  File "/Users/dishb/Coding/test.py", line 20, in __init__
    a, b, c, d = self.coords("cropbox")
    ^^^^^^^^^^
TypeError: cannot unpack non-iterable NoneType object

With the following example:

import customtkinter as ctk

class App(ctk.CTk):
    def __init__(self):

        super().__init__()

        self.grid_rowconfigure(0)
        self.grid_columnconfigure(0)
        
        self.canvas = TestCanvas(self)

class TestCanvas(ctk.CTkCanvas):
    def __init__(self, master):

        super().__init__(master = master)
        
        self.crop_box = [0, 0, 100, 100]
        self.crop_id = self.create_rectangle(self.crop_box, outline="#fff75e", tags="cropbox")
        a, b, c, d = self.coords("cropbox")
        print(a, b, c, d)

if __name__ == "__main__":
    app = App()
    app.mainloop()

On macOS 12.6.7, Python 3.11.4, and CustomTkinter 5.2.0

ghost avatar Jul 15 '23 19:07 ghost

@dpacker780 - Create a PR?

ghost avatar Jul 15 '23 19:07 ghost

Here would be a durable fix to the issue.

    def coords(self, tag_or_id, *args):
        if type(tag_or_id) == str and "ctk_aa_circle_font_element" in self.gettags(tag_or_id):
            coords_id = self.find_withtag(tag_or_id)[0]  # take the lowest id for the given tag
            super().coords(coords_id, *args[:2])

            if len(args) == 3:
                super().itemconfigure(coords_id, font=("CustomTkinter_shapes_font", -int(args[2]) * 2), text=self._get_char_from_radius(args[2]))

        elif type(tag_or_id) == int and tag_or_id in self._aa_circle_canvas_ids:
            super().coords(tag_or_id, *args[:2])

            if len(args) == 3:
                super().itemconfigure(tag_or_id, font=("CustomTkinter_shapes_font", -args[2] * 2), text=self._get_char_from_radius(args[2]))

        else:
            coords = super().coords(tag_or_id, *args)
            if not coords:
                return [0, 0, 0, 0]  # Return default coordinates if None
            return coords

DeltaGa avatar Aug 14 '24 14:08 DeltaGa

This issue is still present, it is such a basic functionality to have a bug there

My workaround is to use directly tkinter.Canvas

super(ctk.CTkCanvas, self.image_view).coords("cropbox")

cnx-tcsikos avatar Sep 02 '25 12:09 cnx-tcsikos