如何动态调整 canvas 的宽度
How to resize the width of the canvas dynamically
我这里有这段代码。就像您看到其中一个按钮中的文本是否很长一样,它不会全部出现。是否有调整 canvas 宽度的解决方案,现在定义为 300,以便显示按钮中的所有文本。我不想手动执行此操作,因为将来文本将从外部文件获取并且数据可能会更改。
任何想法
from tkinter import *
from tkinter.ttk import *
from tkinter import messagebox
from time import strftime
import csv
import xmlrpc.client as xmlrpclib
root = Tk()
frame = Frame(root)
container = Frame(root)
canvas = Canvas(container, borderwidth = 0, highlightthickness = 0, width=300, height=500, bg = "white")
#scrollbar = Scrollbar(container, orient="vertical", command=canvas.yview)
vertibar=Scrollbar(
container,
orient=VERTICAL
)
vertibar.pack(side=RIGHT,fill=Y)
vertibar.config(command=canvas.yview)
horibar=Scrollbar(
container,
orient=HORIZONTAL
)
horibar.pack(side=BOTTOM,fill=X)
horibar.config(command=canvas.xview)
scrollable_frame = Frame(canvas)
# setting the minimum size of the root window
root.geometry("300x650")
# Adding widgets to the root window
Label(root, text='my app',
font=('Verdana', 15)).pack(pady=10)
# tell the canvas how large the frame will be, so that it knows how much it can scroll:
scrollable_frame.bind(
"<Configure>",
lambda e: canvas.configure(
scrollregion=canvas.bbox("all")
)
)
frame_id =canvas.create_window((0, 0), window=scrollable_frame, anchor='nw')
canvas.bind("<Configure>",canvas.itemconfig(frame_id, width=canvas.winfo_reqwidth()))
#canvas.configure(yscrollcommand=scrollbar.set)
canvas.config(
xscrollcommand=horibar.set,
yscrollcommand=vertibar.set
)
# rechner_full = str(rechner[row])
# print(rechner_full)
Button(scrollable_frame, text="text1").pack(fill="both", side="top")
Button(scrollable_frame, text="text2").pack(fill="both", side="top")
Button(scrollable_frame, text="text3").pack(fill="both", side="top")
Button(scrollable_frame, text="longtexxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxt").pack(fill="both", side="top")
# print(button.cget('text'))
container.pack()
canvas.pack(side="left", fill="both")
#scrollbar.pack(side="right", fill="both")
# Button for closing
exit_button = Button(root, text="Beenden", command=root.destroy)
exit_button.pack(pady=20)
root.mainloop()
由于 scrollable_frame
将调整大小以显示最长的按钮,因此您可以在 scrollable_frame
上绑定到 <Configure>
事件的回调中展开 canvas
:
...
scrollable_frame = Frame(canvas)
frame_id =canvas.create_window((0, 0), window=scrollable_frame, anchor='nw')
def on_frame_resized(event):
canvas_width = canvas.winfo_reqwidth()
if event.width > canvas_width:
# expand canvas to the width of scrollable_frame
canvas.configure(width=event.width)
else:
# expand scrollable_frame to the width of canvas
canvas.itemconfigure(frame_id, width=canvas_width)
canvas.configure(scrollregion=canvas.bbox("all"))
# tell the canvas how large the frame will be, so that it knows how much it can scroll:
scrollable_frame.bind("<Configure>", on_frame_resized)
...
但是您需要删除 root.geometry(...)
,因为它会阻止主 window 由于调整 canvas
的大小而扩展。您还需要删除 canvas.bind("<Configure>", ...)
因为它会弄乱 on_frame_resized()
.
所做的工作
...
#root.geometry("300x650")
...
#canvas.bind("<Configure>",canvas.itemconfig(frame_id, width=canvas.winfo_reqwidth()))
...
我这里有这段代码。就像您看到其中一个按钮中的文本是否很长一样,它不会全部出现。是否有调整 canvas 宽度的解决方案,现在定义为 300,以便显示按钮中的所有文本。我不想手动执行此操作,因为将来文本将从外部文件获取并且数据可能会更改。 任何想法
from tkinter import *
from tkinter.ttk import *
from tkinter import messagebox
from time import strftime
import csv
import xmlrpc.client as xmlrpclib
root = Tk()
frame = Frame(root)
container = Frame(root)
canvas = Canvas(container, borderwidth = 0, highlightthickness = 0, width=300, height=500, bg = "white")
#scrollbar = Scrollbar(container, orient="vertical", command=canvas.yview)
vertibar=Scrollbar(
container,
orient=VERTICAL
)
vertibar.pack(side=RIGHT,fill=Y)
vertibar.config(command=canvas.yview)
horibar=Scrollbar(
container,
orient=HORIZONTAL
)
horibar.pack(side=BOTTOM,fill=X)
horibar.config(command=canvas.xview)
scrollable_frame = Frame(canvas)
# setting the minimum size of the root window
root.geometry("300x650")
# Adding widgets to the root window
Label(root, text='my app',
font=('Verdana', 15)).pack(pady=10)
# tell the canvas how large the frame will be, so that it knows how much it can scroll:
scrollable_frame.bind(
"<Configure>",
lambda e: canvas.configure(
scrollregion=canvas.bbox("all")
)
)
frame_id =canvas.create_window((0, 0), window=scrollable_frame, anchor='nw')
canvas.bind("<Configure>",canvas.itemconfig(frame_id, width=canvas.winfo_reqwidth()))
#canvas.configure(yscrollcommand=scrollbar.set)
canvas.config(
xscrollcommand=horibar.set,
yscrollcommand=vertibar.set
)
# rechner_full = str(rechner[row])
# print(rechner_full)
Button(scrollable_frame, text="text1").pack(fill="both", side="top")
Button(scrollable_frame, text="text2").pack(fill="both", side="top")
Button(scrollable_frame, text="text3").pack(fill="both", side="top")
Button(scrollable_frame, text="longtexxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxt").pack(fill="both", side="top")
# print(button.cget('text'))
container.pack()
canvas.pack(side="left", fill="both")
#scrollbar.pack(side="right", fill="both")
# Button for closing
exit_button = Button(root, text="Beenden", command=root.destroy)
exit_button.pack(pady=20)
root.mainloop()
由于 scrollable_frame
将调整大小以显示最长的按钮,因此您可以在 scrollable_frame
上绑定到 <Configure>
事件的回调中展开 canvas
:
...
scrollable_frame = Frame(canvas)
frame_id =canvas.create_window((0, 0), window=scrollable_frame, anchor='nw')
def on_frame_resized(event):
canvas_width = canvas.winfo_reqwidth()
if event.width > canvas_width:
# expand canvas to the width of scrollable_frame
canvas.configure(width=event.width)
else:
# expand scrollable_frame to the width of canvas
canvas.itemconfigure(frame_id, width=canvas_width)
canvas.configure(scrollregion=canvas.bbox("all"))
# tell the canvas how large the frame will be, so that it knows how much it can scroll:
scrollable_frame.bind("<Configure>", on_frame_resized)
...
但是您需要删除 root.geometry(...)
,因为它会阻止主 window 由于调整 canvas
的大小而扩展。您还需要删除 canvas.bind("<Configure>", ...)
因为它会弄乱 on_frame_resized()
.
...
#root.geometry("300x650")
...
#canvas.bind("<Configure>",canvas.itemconfig(frame_id, width=canvas.winfo_reqwidth()))
...