tkinter - Why is there such a thing like bbox?

為{幸葍}努か 提交于 2020-12-31 11:49:32

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!