Tkinter canvas (FigureCanvasTkAgg) bbox gives None
Question:
Met strange problem : canvas.bbox('ALL')
gives None
.
SO topics say that canvas
only have coords to give when there some is .create_xxx()
methods in code. The thing is that class FigureCanvasTkAgg
in its __init__
method use create_image
method and I think in my little snippet, when I create instance of thic Class it should give me some coordinate box when call instance.bbox
command. But it’s not…
self.Frame = Frame(root, bg = 'white')
self.Frame.place (relx = 0.37 , rely = 0.05 , relheight = 0.85 , relwidth = 0.51)
self.canvas = FigureCanvasTkAgg ( fig , master = self.Frame) # A tk.DrawingArea.
self.canvas.get_tk_widget ().place ( relx = 0 , rely = 0)
self.canvas.get_tk_widget ().config ( yscrollcommand = self.vbar.set ,
scrollregion = (0,0,w,639*h/10 ))
self.canvas.get_tk_widget ().update_idletasks ()
print(self.canvas.get_tk_widget ().winfo_width(),self.canvas.get_tk_widget ().winfo_height() )
self.Frame.update_idletasks ()
print(self.canvas.get_tk_widget ().bbox('ALL'))
self.toolbar = NavigationToolbar2Tk ( self.canvas , self.Frame )
self.vbar.pack ( side = RIGHT , fill = Y)
Answers:
Met strange problem : canvas.bbox(‘ALL’) gives None.
When you use 'ALL'
, it is looking for all canvas objects with the tag 'ALL'
and not finding any.
If you want the bounding box of all objects, the correct argument to bbox
is 'all'
, not 'ALL'
. The literal string “all” is treated as a special case by the canvas to represent all objects on the canvas.
@BryanOakley ‘s answer is really an important clarification.
The excellent documentation by the late John Shipman, unfortunately, does have an error for present-day tkinter. It stated that:
.bbox(tagOrId=None)
Returns a tuple (x1, y1, x2, y2) describing a rectangle that encloses all the objects
specified by tagOrId. If the argument is omitted, returns a rectangle enclosing all objects
on the canvas. The top left corner of the rectangle is (x1, y1) and the bottom right corner
is (x2, y2).
Presently, if canvas.bbox()
is used, tkinter returns _tkinter.TclError: wrong # args: should be ".!xxxxxxx bbox tagOrId ?tagOrId ...?"
There are online tkinter documents that advocate using ALL
. An example is this one. However, most readers would have been oblivious that the from tkinter import *
statement had been used to import all tkinter objects, which is also not in line with PEP8 guidelines on import
statements. A good practice for importing tkinter is to use import tkinter as tk
. Following this, your statement should either be:
print(self.canvas.get_tk_widget().bbox(tk.ALL))
or
print(self.canvas.get_tk_widget().bbox('all'))
Summarising: Either use .bbox(tk.ALL)
or .bbox('all')
on a tk.Canvas
object/instance.
Met strange problem : canvas.bbox('ALL')
gives None
.
SO topics say that canvas
only have coords to give when there some is .create_xxx()
methods in code. The thing is that class FigureCanvasTkAgg
in its __init__
method use create_image
method and I think in my little snippet, when I create instance of thic Class it should give me some coordinate box when call instance.bbox
command. But it’s not…
self.Frame = Frame(root, bg = 'white')
self.Frame.place (relx = 0.37 , rely = 0.05 , relheight = 0.85 , relwidth = 0.51)
self.canvas = FigureCanvasTkAgg ( fig , master = self.Frame) # A tk.DrawingArea.
self.canvas.get_tk_widget ().place ( relx = 0 , rely = 0)
self.canvas.get_tk_widget ().config ( yscrollcommand = self.vbar.set ,
scrollregion = (0,0,w,639*h/10 ))
self.canvas.get_tk_widget ().update_idletasks ()
print(self.canvas.get_tk_widget ().winfo_width(),self.canvas.get_tk_widget ().winfo_height() )
self.Frame.update_idletasks ()
print(self.canvas.get_tk_widget ().bbox('ALL'))
self.toolbar = NavigationToolbar2Tk ( self.canvas , self.Frame )
self.vbar.pack ( side = RIGHT , fill = Y)
Met strange problem : canvas.bbox(‘ALL’) gives None.
When you use 'ALL'
, it is looking for all canvas objects with the tag 'ALL'
and not finding any.
If you want the bounding box of all objects, the correct argument to bbox
is 'all'
, not 'ALL'
. The literal string “all” is treated as a special case by the canvas to represent all objects on the canvas.
@BryanOakley ‘s answer is really an important clarification.
The excellent documentation by the late John Shipman, unfortunately, does have an error for present-day tkinter. It stated that:
.bbox(tagOrId=None)
Returns a tuple (x1, y1, x2, y2) describing a rectangle that encloses all the objects
specified by tagOrId. If the argument is omitted, returns a rectangle enclosing all objects
on the canvas. The top left corner of the rectangle is (x1, y1) and the bottom right corner
is (x2, y2).
Presently, if canvas.bbox()
is used, tkinter returns _tkinter.TclError: wrong # args: should be ".!xxxxxxx bbox tagOrId ?tagOrId ...?"
There are online tkinter documents that advocate using ALL
. An example is this one. However, most readers would have been oblivious that the from tkinter import *
statement had been used to import all tkinter objects, which is also not in line with PEP8 guidelines on import
statements. A good practice for importing tkinter is to use import tkinter as tk
. Following this, your statement should either be:
print(self.canvas.get_tk_widget().bbox(tk.ALL))
or
print(self.canvas.get_tk_widget().bbox('all'))
Summarising: Either use .bbox(tk.ALL)
or .bbox('all')
on a tk.Canvas
object/instance.