问题
Now that I'm working more with tkinter Canvas I was wondering about the use of bbox.
For me I'm using bbox to get the coords of an element but the Canvas already have a method to return the coords of an item. So why did they invent something like bbox?
Comparing the official tcl description here:
bbox
pathName bbox tagOrId ?tagOrId tagOrId ...?
Returns a list with four elements giving an approximate bounding box for all the items named by the tagOrId arguments. The list has the form ``x1 y1 x2 y2'' such that the drawn areas of all the named elements are within the region bounded by x1 on the left, x2 on the right, y1 on the top, and y2 on the bottom. The return value may overestimate the actual bounding box by a few pixels. If no items match any of the tagOrId arguments or if the matching items have empty bounding boxes (i.e. they have nothing to display) then an empty string is returned.
coords
pathName coords tagOrId ?coordList?
Query or modify the coordinates that define an item. If no coordinates are specified, this command returns a list whose elements are the coordinates of the item named by tagOrId. If coordinates are specified, then they replace the current coordinates for the named item. If tagOrId refers to multiple items, then the first one in the display list is used.
I see the difference between these, but can't imaging in which case I would need a bbox instead of the coords? Can someone teach me a better understanding of this please?
回答1:
The difference is that with bbox()
you can get the bounding box of a group of items (using a tag or 'all') while coords()
returns the coordinates of the first item with given tag. Here is an example
import tkinter as tk
root = tk.Tk()
canvas = tk.Canvas(root)
canvas.pack()
i1 = canvas.create_rectangle(10, 10, 30, 50, tags='rect')
i2 = canvas.create_rectangle(60, 80, 70, 120, fill='red', tags='rect')
canvas.update_idletasks()
print('bbox', canvas.bbox('rect'))
print('coords', canvas.coords('rect'))
which gives
bbox
(9, 9, 71, 121)
coords
[10.0, 10.0, 30.0, 50.0]
One of the typical use of bbox()
is when you want to scroll a group of widgets using a canvas: The scrollregion of the canvas needs to be set to include all the canvas content so canvas.bbox('all')
is quite useful. See for instance Adding a scrollbar to a group of widgets in Tkinter (in the onFrameConfigure()
function).
回答2:
Understanding bbox
Lets take this bit of Code here:
import tkinter as tk
def do_bbx(event):
item_id = event.widget.find_withtag('current')[0]
crds = event.widget.coords(item_id)
print(f'{item_id} was clicked')
print(f'bbox returns, {bbx}')
print(f'coords returns, {crds}')
root = tk.Tk()
c = tk.Canvas(root,width=250,height=250)
f = c.create_rectangle(10,20, 50, 50,
fill = "BLUE")
sec = c.create_rectangle(30,30, 80, 80,
fill = "GREEN")
bbx = c.bbox(f, sec)
c.tag_bind('all', "<Button-1>", do_bbx)
c.pack()
root.mainloop()
and run this which return into this:
If you click on the blue rectangle the following will be printed out:
1 was clicked
bbox returns, (9, 19, 81, 81)
coords returns, [10.0, 20.0, 50.0, 50.0]
While clicking on the green will print:
2 was clicked
bbox returns, (9, 19, 81, 81)
coords returns, [30.0, 30.0, 80.0, 80.0]
So bbox does just quiet else then compareing the values of the coordinates and returns us a list. Like:
import tkinter as tk
def rectangel_us(canvas, *items):
coords = {"x1":[],"y1":[],"x2":[],"y2":[]}
for i in items:
coords['x1'].append(canvas.coords(i)[0])
coords['y1'].append(canvas.coords(i)[1])
coords['x2'].append(canvas.coords(i)[2])
coords['y2'].append(canvas.coords(i)[3])
x1 = min(coords['x1'])-1
y1 = min(coords['y1'])-1
x2 = max(coords['x2'])+1
y2 = max(coords['y2'])+1
return[x1,y1,x2,y2]
root = tk.Tk()
c = tk.Canvas(root,width=250,height=250)
f = c.create_rectangle(10,20, 50, 50,
fill = "BLUE")
sec = c.create_rectangle(30,30, 80, 80,
fill = "GREEN")
bbx = rectangel_us(c, f, sec)
print(bbx)
c.pack()
root.mainloop()
the printed out bbx will be:
[9.0, 19.0, 81.0, 81.0]
as we know from above.
This can be visible by this code here:
import tkinter as tk
def rectangel_us(canvas, *items):
coords = {"x1":[],"y1":[],"x2":[],"y2":[]}
for i in items:
coords['x1'].append(canvas.coords(i)[0])
coords['y1'].append(canvas.coords(i)[1])
coords['x2'].append(canvas.coords(i)[2])
coords['y2'].append(canvas.coords(i)[3])
x1 = min(coords['x1'])-1
y1 = min(coords['y1'])-1
x2 = max(coords['x2'])+1
y2 = max(coords['y2'])+1
canvas.create_rectangle(x1,y1,x2,y2,
outline='red')
root = tk.Tk()
c = tk.Canvas(root,width=250,height=250)
f = c.create_rectangle(10,20, 50, 50,
fill = "BLUE")
sec = c.create_rectangle(30,30, 80, 80,
fill = "GREEN")
bbx = rectangel_us(c, f, sec)
c.pack()
root.mainloop()
Which result in this:
来源:https://stackoverflow.com/questions/62712481/tkinter-why-is-there-such-a-thing-like-bbox