Bug report
Double nested arrays in tk.coords will produce errors in tkinter (_tkinter.TclError: wrong # coordinates: expected at least 4, got 2 in this case)
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 while canvas.create_line([[100, 100], [300, 300]]) would work
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 2
Supporting 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 while canvas.create_line([[100, 100], [300, 300]]) does?
The Python wrapper for the create_* methods flattens arguments, basically turning canvas.create_line((startX, startY), (stopX, stopY)) into canvas.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 the coords wrapper.
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 [-]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,
defcoords(self, *args):
"""Return a list of coordinates for the item given in ARGS."""# XXX Should use _flatten on argsreturn [self.tk.getdouble(x) forxinself.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
It would be a new feature. And I agree that it is worth to use _flatten on args. Tk canvas subcommands coord and create has the same signature for coordinates. It natively supports both canvas.coords(line, 100, 100, 200, 200) and canvas.coords(line, [100, 100, 200, 200]), but unfortunately not more natural in Python canvas.coords(line, [100, 100], [200, 200]) and canvas.coords(line, [[100, 100], [200, 200]]).
Activity
Why-not-now commented on Jul 1, 2022
Upon further inspection, it seems that canvas.coords do not allow doubly nested loops
stevendaprano commented on Jul 1, 2022
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.
Why-not-now commented on Jul 1, 2022
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 while canvas.create_line([[100, 100], [300, 300]]) would work
Why-not-now commented on Jul 1, 2022
Example of this is
ronaldoussoren commented on Jul 1, 2022
As mentioned on discuss.python.org the coords method requires at least 4 coordinates, not 2. The error message states this:
Supporting 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.
Why-not-now commented on Jul 1, 2022
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 while canvas.create_line([[100, 100], [300, 300]]) does?
ronaldoussoren commented on Jul 2, 2022
Good question. To be honest I'm not a Tkinter expert.
Looking at the implementation and Tk documentation:
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 the coords wrapper.
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.
Why-not-now commented on Jul 3, 2022
Looking through the source code, at line 2817 of tkinter/__init__.py,
there is one comment saying they should use _flatten on args.
serhiy-storchaka commented 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 coord and create has the same signature for coordinates. It natively supports both canvas.coords(line, 100, 100, 200, 200) and canvas.coords(line, [100, 100, 200, 200]), but unfortunately not more natural in Python canvas.coords(line, [100, 100], [200, 200]) and canvas.coords(line, [[100, 100], [200, 200]]).
Add more tkinter.Canvas tests
Add more tkinter.Canvas tests
Add more tkinter.Canvas tests (GH-98475)
Add more tkinter.Canvas tests (pythonGH-98475)
Add more tkinter.Canvas tests (pythonGH-98475)
Add more tkinter.Canvas tests (GH-98475)
pythongh-94473: Flatten arguments in tkinter.Canvas.coords()
[3.10] Add more tkinter.Canvas tests (GH-98475) (#98477)
gh-94473: Flatten arguments in tkinter.Canvas.coords() (GH-98479)