25

I'm developing a small Tkinter GUI to draw matplotlib-plots. (It contains a few Entries and assembles the plot according to their content.)

I have designed my plotting widget according to http://matplotlib.org/examples/user_interfaces/embedding_in_tk.html, only I use grid instead of pack:

canvas = FigureCanvasTkAgg(fig, master=root)
canvas.get_tk_widget().grid(row=1,column=4,columnspan=3,rowspan=20)

That part works. But embedding the NavigationToolbar in the same fashion does not. Tkinter breaks down without error when I include the lines:

toolbar = NavigationToolbar2TkAgg( canvas, root )
canvas._tkcanvas.grid(row=22,column=4)

I know this is because NavigationToolbar calls pack internally, and pack and grid don't get along. However, I like grid and would hate to have to redesign my whole GUI just to be able to use the NavigationToolbar.

Is there a workaround so I can use NavigationToolbar2TkAgg via grid? (I have found the advice to "subclass and overload" here, but don't know how to do that.)

Any help greatly appreciated!

4 Answers 4

18

Can you create an empty frame, then put the NavigationToolbar in that frame? I assume the NavigationToolbar will then pack itself in that frame. You can then use grid on the frame.

Sign up to request clarification or add additional context in comments.

2 Comments

I have tried that: toolbar_frame = Frame(root) toolbar_frame.grid(row=21,column=4,columnspan=2) toolbar = NavigationToolbar2TkAgg( canvas, toolbar_frame ) That does display the Navigation Toolbar, thank you! But it does not seem to be connected to the FigureCanvas?
I just tested the trick for my application. The toolbar acts as expected on the canvas. So I think the answer is yes.
15

Here is a code example for what was mentioned in Bryan Oakleys answer (add toolbar to frame, place frame on grid):

    fig = Figure(figsize=(5, 5), dpi=100)

    canvas = FigureCanvasTkAgg(fig, master=root)
    canvas.get_tk_widget().grid(row=1,column=4,columnspan=3,rowspan=20)
    # here: plot suff to your fig
    canvas.draw()

    ###############    TOOLBAR    ###############
    toolbarFrame = Frame(master=root)
    toolbarFrame.grid(row=22,column=4)
    toolbar = NavigationToolbar2TkAgg(canvas, toolbarFrame)

Comments

4

I believe what you're looking for is the pack_toolbar=False kwarg
Your toolbar definition should look something like this:

toolbar = NavigationToolbar2Tk(canvas, root, pack_toolbar=False)

The following two lines are executed within the NavigationToolbar2TK constructor:

if pack_toolbar:
        self.pack(side=tk.BOTTOM, fill=tk.X)

So setting pack_toolbar to False disables the internal packing, allowing you to use to use grid as per usual.

toolbar.grid()

Comments

1
# the following works for me. I created an empty frame and display it using the grid
# management system, so the frame will be able to use pack management system
canvas = FigureCanvasTkAgg(fig, root)
canvas.draw()
canvas.get_tk_widget().grid(row=2, column=0)
frame = Frame(root)
frame.grid(row=0, column=1)
toobar = NavigationToolbar2Tk(canvas, frame)
canvas.get_tk_widget().grid(row=1, column=0)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.