You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Tkinter Canvas.coords does not flatten arguments #94473
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 commentedon Jul 1, 2022
Upon further inspection, it seems that canvas.coords do not allow doubly nested loops
stevendaprano commentedon 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 commentedon 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 whilecanvas.create_line([[100, 100], [300, 300]])would workWhy-not-now commentedon Jul 1, 2022
Example of this is
ronaldoussoren commentedon 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 commentedon 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 whilecanvas.create_line([[100, 100], [300, 300]])does?ronaldoussoren commentedon Jul 2, 2022
Good question. To be honest I'm not a Tkinter expert.
Looking at the implementation and Tk documentation:
canvas.create_line((startX, startY), (stopX, stopY))intocanvas.create_line(startX, startY, stopX, stopY)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.[-]Numpy array not compatible with tkinter[/-][+]Inconsistent results for canvas.coords and canvas.create_<widget>[/+][-]Inconsistent results for canvas.coords and canvas.create_<widget>[/-][+]Tkinter Canvas.coords does not flatten arguments[/+]Why-not-now commentedon 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 commentedon 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]]).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)