python tk tkinter не может позволить себе несколько холстов в моем прокручиваемом фрейме

#python-3.x #tkinter #canvas #frame

#python-3.x #tkinter #холст #фрейм

Вопрос:

 import tkinter as tk
from tkinter import filedialog
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg,  NavigationToolbar2Tk) 
from matplotlib.figure import Figure 
import matplotlib.pyplot as plt
from data import dataprocess
root = tk.Tk()
root.geometry('1500x800')
container = tk.Frame(root)
main_canvas = tk.Canvas(container, width=1480, height=800,  bg='blue')
scrollbar = tk.Scrollbar(container, orient="vertical", command=main_canvas.yview)
scrollable_frame = tk.Canvas(main_canvas, bg='black')
scrollable_frame.bind(
"<Configure>",
lambda e: main_canvas.configure(
    scrollregion=main_canvas.bbox("all")
    )
)

main_canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")

main_canvas.configure(yscrollcommand=scrollbar.set)

for i in range(100):
    f = Figure(figsize=(5,5), dpi=100)
    a = f.add_subplot(111)
    a.plot([1,2,3,4,5,6,7,8],[5,6,1,3,8,9,3,5])
    a.set_title("fig"   str(i))
    canvas = FigureCanvasTkAgg(f, 
                           master = scrollable_frame)
    canvas.draw()
    canvas.get_tk_widget().grid(row=i, column=0)

container.grid()
main_canvas.grid()
scrollbar.grid(row=0, column=1, sticky="nse")
container.mainloop()
  

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

Комментарии:

1. Прокручиваемый фрейм должен быть фреймом, а не холстом.

2. Может использоваться несколько столбцов вместо одного столбца. Или использовать main_canvas.create_window() вместо прокручиваемого фрейма. Однако ваш подход значительно снизит производительность вашей системы.

Ответ №1:

Я предположу и скажу, что вам действительно нужен виджет ScrolledText. Попробуйте это:

 import tkinter as tk
from tkinter.scrolledtext import ScrolledText
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg,  NavigationToolbar2Tk)
from matplotlib.figure import Figure

root = tk.Tk()
root.geometry('1500x800')
scrollable_frame = ScrolledText(root)
scrollable_frame.pack(expand=True, fill=tk.BOTH)

for i in range(10):
    f = Figure(figsize=(5,5), dpi=100)
    a = f.add_subplot(111)
    a.plot([1,2,3,4,5,6,7,8],[5,6,1,3,8,9,3,5])
    a.set_title("fig"   str(i))
    canvas = FigureCanvasTkAgg(f)
    scrollable_frame.window_create(tk.END, window=canvas.get_tk_widget())
    scrollable_frame.insert(tk.END, 'n')

root.mainloop()
  

100 графиков будут очень обременительными, несмотря ни на что, для компьютера и человека. Я думаю, было бы лучше спроектировать вашу программу по-другому, чтобы график обновлялся, а не прокручивался через множество графиков.

Комментарии:

1. Приведенный выше код сработал! Что я могу сделать, если я хочу использовать метод «сетка» вместо метода «пакет». Я также хочу добавить некоторые виджеты, такие как кнопки и метки в ScrolledText. Благодарю за ваше предложение о моем назначении, однако оно предназначено для конкретной цели.

2. Виджеты не используют сетку или пакет внутри текста или холста, вы используете их только при добавлении к типу фрейма. Чтобы добавить кнопки, вы должны добавить их с window_create помощью метода, точно так же, как я использовал для графика. Вы также можете добавлять метки таким образом, но текстовый виджет поддерживает необработанный текст, поэтому вы, вероятно, захотите использовать insert() его для этого. Чтобы поместить текстовый объект в корневое окно, я использовал pack() , но вы можете просто поменять его на grid(), если хотите.

3. Я добился успеха. Вот новая проблема, связанная с тем, что я хочу изменить только рисунок 1 ~ 5 без перерисовки всех рисунков. Есть предложения?

4. @curry просто сохраните ссылку на график и обновите ее с помощью set_data(). Если вам нужна помощь в этом, создайте новый пост.

5. Возможно, я знаю, что вы имеете в виду. Я до сих пор понятия не имею, как поместить идентификатор ссылки на каждый график и обновить с помощью set_data(). Не могли бы вы дать мне какой-нибудь пример кода или ссылочную ссылку. Я ценю это.