Python Tkinter Embed Matplotlib в графическом интерфейсе

Я пытаюсь встроить графику в свой графический интерфейс Tkinter, закодированный в Python. Я считаю, что приведенный ниже код преуспевает в том, чтобы просто поместить график в холст, но у меня нет никакого контроля над расположением холста в сетке графического интерфейса. Я хочу иметь подзаголовок моего графического интерфейса - сюжет... не полностью. Как я могу поместить этот виджет холста?

#!/usr/apps/Python/bin/python
import matplotlib, sys
matplotlib.use('TkAgg')
from numpy import arange, sin, pi
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
from Tkinter import *

master = Tk()
master.title("Hello World!")
#-------------------------------------------------------------------------------

f = Figure(figsize=(5,4), dpi=100)
a = f.add_subplot(111)
t = arange(0.0,3.0,0.01)
s = sin(2*pi*t)
a.plot(t,s)


dataPlot = FigureCanvasTkAgg(f, master=master)
dataPlot.show()
dataPlot.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
#-------------------------------------------------------------------------------
master.mainloop()

Ответы

Ответ 1

У вас нет других виджетов, поэтому вам сложно узнать, где вы хотите других виджетов. Вот что я могу вам сказать: делая dataPlot.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1), вы просите Tkinter заполнить экран сюжетом. Это, потому что вы просите его заполнить все направления (fill=BOTH) и развернуть, чтобы заполнить любое дополнительное пространство (expand=1).

Однако вы можете добавить другие виджеты. pack работает, помещая виджеты на одну сторону контейнера. Ваш контейнер master всегда имеет четыре стороны. Например, если вы хотите создать панель инструментов, вы бы сделали что-то вроде:

toolbar = tk.Frame(master)
button = tk.Button(toolbar, text="Push me")
button.pack(side="left") # left side of parent, the toolbar frame
toolbar.pack(side=TOP, fill="x") # top of parent, the master window

Обратите внимание, что если вы поместите этот код после кода, где вы pack заговора, панель инструментов появится внизу! Это потому, что TOP, BOTTOM и т.д. Относятся к пробелу, оставшемуся после любых других виджетов, которые уже были pack ed. Сюжет занимает верх, оставшееся пространство находится внизу. Поэтому, когда вы укажете TOP снова, это означает "наверху области ниже того, что уже находится наверху".

Итак, у вас есть выбор. Лучший выбор - сделать ваши виджеты в том порядке, в котором вы хотите, чтобы они появились. Если вы pack панели инструментов наверху перед вами pack сюжет, это будет панель инструментов, которая отображается вверху. Кроме того, вы можете разместить график внизу, а не сверху, и это также решит проблему.

Кстати, я обычно создаю свои виджеты в одном блоке, а затем выкладываю их в отдельный блок. Я нахожу, что код упрощает его работу.

Другим выбором, который лучше подходит для вашей ментальной модели, является grid вместо pack. С помощью grid вы можете выбрать строки и столбцы (столбцы), которые занимает виджет. Это упрощает прокладку вещей в сетке, но за счет использования небольшого количества кода.

Например, чтобы разместить панель инструментов сверху и график ниже, вы можете сделать:

toolbar.grid(row=1, column=1, sticky="ew")
dataPlot.get_tk_widget().grid(row=1, column=1, sticky="nsew")
master.grid_rowconfigure(0, weight=0)
master.grid_rowconfigure(1, weight=1)
master.grid_columnconfigure(0, weight=1)

Обратите внимание, что строки и столбцы начинаются с нуля. Кроме того, "вес" означает, насколько этот виджет расширяется относительно других виджетов. С двумя рядами одинакового веса они будут одинаково расширяться при изменении размера окна. Вес нуля означает отсутствие расширения. Вес 2 для одной строки и 1 для другого означает, что первый будет увеличиваться вдвое больше, чем последний.

Для получения дополнительной информации см. эту страницу в сетке и эту страницу на пакет.