#python #tkinter #tkinter-canvas
#python #tkinter #tkinter-холст
Вопрос:
Итак, я хочу иметь вертикальную и горизонтальную полосу прокрутки в окне, которая автоматически обновляется для размера холста. Я частично понял это, и прямо сейчас код создает дополнительные полосы прокрутки для каждого обновления, а горизонтальная полоса прокрутки не охватывает длину всего холста. Вот пример, который я создал, чтобы проиллюстрировать это:
import tkinter
from tkinter import ttk
root = tkinter.Tk()
root.state("zoomed")
bigframe = tkinter.Frame(root)
bigframe.pack(fill="both", expand=1)
canvas = tkinter.Canvas(bigframe)
canvas.pack(side="left", fill="both", expand=1)
scrollbarv = ttk.Scrollbar(bigframe, orient="vertical", command=canvas.yview)
scrollbarh = ttk.Scrollbar(bigframe, orient="horizontal", command=canvas.xview)
scrollbarv.pack(side="right", fill="y")
scrollbarh.pack(side="bottom", fill="x")
canvas.configure(yscrollcommand=scrollbarv.set, xscrollcommand=scrollbarh.set)
canvas.bind("<Configure>", lambda e: canvas.configure(scrollregion=canvas.bbox("all")))
mainframe = tkinter.Frame(canvas)
canvas.create_window((0, 0), window=mainframe, anchor="nw")
i = 1
text = "Hello World! "
def click():
global i
global text
for t in range(10):
i = 1
text = "Hello World! "
tkinter.Label(mainframe, text=text).pack()
scrollbar = ttk.Scrollbar(bigframe, orient="vertical", command=canvas.yview)
scrollbar.pack(side="right", fill="y")
button = tkinter.Button(mainframe, text="Click me!", command=click)
button.pack()
root.mainloop()
Это то, что происходит, когда я нажимаю кнопку 4 раза:
Я считаю, что небольшая горизонтальная полоса прокрутки связана с тем, что я говорю canvas.pack(side="left", fill="both", expand=1)
, но если я скажу side="top
, то вертикальные полосы прокрутки не охватывают высоту холста. Есть ли какой-то конкретный фрагмент кода, который вызывает проблему с несколькими полосами прокрутки или проблему с горизонтальной полосой? И если да, то как мне это исправить?
Ответ №1:
Вы должны уничтожить старую полосу прокрутки, прежде чем добавлять новую. Просто добавьте scrollbar.destroy() в свою функцию щелчка, как я сделал ниже:
def click():
global i
global text
for t in range(10):
i = 1
text = "Hello World! "
tkinter.Label(mainframe, text=text).pack()
scrollbar = ttk.Scrollbar(bigframe, orient="vertical", command=canvas.yview)
scrollbar.destroy()
scrollbar.pack(side="right", fill="y")
Я внес следующие изменения в ваш код. Сначала это не работает, однако, если я изменяю размер окна, оно работает отлично.
import tkinter
from tkinter import ttk
root = tkinter.Tk()
root.state("zoomed")
bigframe = tkinter.Frame(root)
bigframe.pack(fill="both", expand=1)
canvas = tkinter.Canvas(bigframe)
canvas.pack(side="left", fill="both", expand=1)
scrollbarv = ttk.Scrollbar(bigframe, orient="vertical",
command=canvas.yview)
scrollbarh = ttk.Scrollbar(root, orient="horizontal",
command=canvas.xview)
scrollbarv.pack(side="right", fill="y")
scrollbarh.pack(side="bottom", fill="x")
canvas.configure(yscrollcommand=scrollbarv.set,
xscrollcommand=scrollbarh.set)
canvas.bind("<Configure>", lambda e:
canvas.configure(scrollregion=canvas.bbox("all")))
mainframe = tkinter.Frame(canvas)
canvas.create_window((0, 0), window=mainframe, anchor="nw")
i = 1
text = "Hello World! "
def updateScrollRegion():
canvas.update_idletasks()
canvas.config(scrollregion=mainframe.bbox())
def click():
global i, scrollbarv, text
for t in range(10):
i = 1
text = "Hello World! "
tkinter.Label(mainframe, text=text).pack()
button = tkinter.Button(mainframe, text="Click me!", command=click)
button.pack()
root.mainloop()
Комментарии:
1. Когда я пытаюсь это сделать, полоса прокрутки становится серой и не прокручивается. Тем не менее, спасибо за предложение. Знаете ли вы, нужно ли перемещать некоторые строки, чтобы он работал с этим методом?
2. Спасибо за ваше предложение. Используя вашу идею, я смог исправить это и устранить проблему с несколькими столбцами, повозившись с некоторыми глобальными переменными
3. О, это здорово, никаких проблем. Не могли бы вы опубликовать рабочий код, я хотел бы его увидеть.
4. Я воспользовался вашим первым предложением и переместил команду destroy над командой ttk.Scrollbar, а глобальную полосу прокрутки разместил в верхней части функции. Я могу попробовать переделать код, если вы хотите, чтобы я, но я сделал это только в качестве примера, чтобы проиллюстрировать мою проблему, и это сильно отличается от моего основного программного кода.
5. Еще одна вещь, которую я изучил, это gist.github.com/novel-yet-trivial /… , который представляет собой двойную рамку полосы прокрутки от novel-yet-trivial, и он прекрасно работает, упрощая процесс