Repository navigation
Tkinter Canvas.coords does not flatten arguments #94473
Description
Activity
- addedtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
on Jul 1, 2022 Upon further inspection, it seems that canvas.coords do not allow doubly nested loops
Is there something that suggests to you that using a numpy array for coords ought to work?
I don't know what you mean by double nested loops. There's no loop here.
Because the numpy array is similar to a list, and lists works for
canvas.create_line()etc.Also doubly nested would be a list inside a list. So
canvas.coords(line, [[100, 100], [300, 300]])wouldn't work whilecanvas.create_line([[100, 100], [300, 300]])would workExample of this is
import numpy as np import tkinter as tk root = tk.Tk() canvas = tk.Canvas(width=400, height=400, background="bisque") canvas.pack(fill="both", expand=True) line = canvas.create_line([[100, 100], [300, 300]]) canvas.coords(line, [[100, 100], [200, 200]]) # line with error root.mainloop()```
As mentioned on discuss.python.org the coords method requires at least 4 coordinates, not 2. The error message states this:
_tkinter.TclError: wrong # coordinates: expected at least 4, got 2Supporting numpy arrays for coordinates, or rather anything other than builtin lists and tuples, could be a feature request, but would require a clear use case that sells this change.
I see, thanks for the help. Just one more question before I close this issue, why does
canvas.coords(line, [[100, 100], [200, 200]])not represent 4 coordinates whilecanvas.create_line([[100, 100], [300, 300]])does?Good question. To be honest I'm not a Tkinter expert.
Looking at the implementation and Tk documentation:
- The Tk implementation represents the various x, y coordinates as separate arguments (see https://www.tcl.tk/man/tcl8.0/TkCmd/canvas.html#M40)
- The Python wrapper for the create_* methods flattens arguments, basically turning
canvas.create_line((startX, startY), (stopX, stopY))intocanvas.create_line(startX, startY, stopX, stopY) - The Python wrapper for coord method does not flatten, which means you have to pass the various coordinates as separate arguments (
canvas.coords(line, startX, startY, stopX, stopY))
I don't know if that's intentional, but is does feel inconsistent. That said,
canvas.coords(line)will return the current coordinates of the line (or other object) as an flattened list as well. Changing that is not backward compatible and IMHO is not worth changing even if we'd add argument flattening to thecoordswrapper.If you don't mind I'll change to title of this issue to
Tkinter Canvas.coords does not flatten arguments, and leave it open for someone that knows more about Tk to comment on whether or not this is intentional behaviour.- changed the title
[-]Numpy array not compatible with tkinter[/-][+]Inconsistent results for canvas.coords and canvas.create_<widget>[/+]on Jul 2, 2022 - changed the title
[-]Inconsistent results for canvas.coords and canvas.create_<widget>[/-][+]Tkinter Canvas.coords does not flatten arguments[/+]on Jul 2, 2022 Looking through the source code, at line 2817 of tkinter/__init__.py,
def coords(self, *args): """Return a list of coordinates for the item given in ARGS.""" # XXX Should use _flatten on args return [self.tk.getdouble(x) for x in self.tk.splitlist( self.tk.call((self._w, 'coords') + args))]
there is one comment saying they should use _flatten on args.
Reacted by Akuli, Benedek Dévényi, Serhiy Storchaka and Why-not-now- addedtype-featureA feature request or enhancementA feature request or enhancementand removedtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
on Oct 14, 2022 It would be a new feature. And I agree that it is worth to use _flatten on args. Tk canvas subcommands
coordandcreatehas the same signature for coordinates. It natively supports bothcanvas.coords(line, 100, 100, 200, 200)andcanvas.coords(line, [100, 100, 200, 200]), but unfortunately not more natural in Pythoncanvas.coords(line, [100, 100], [200, 200])andcanvas.coords(line, [[100, 100], [200, 200]]).- added a commit that references this issue
on Oct 20, 2022 - added a commit that references this issue
on Oct 28, 2022
Bug report
Double nested arrays in tk.coords will produce errors in tkinter (
_tkinter.TclError: wrong # coordinates: expected at least 4, got 2in this case)Your environment
Linked PRs