我一直在使用tkinter 和 tkinter.ttk在 python 中制作这个下载器应用程序,并在应用程序中添加了一个最近的功能,供用户查看程序以前执行的操作的日志。它工作正常,但是,我最近发现了一个错误。
我有一个设置按钮,它创建另一个 Toplevel,然后您可以管理默认目录并使用三个ttk.Radiobuttons将应用程序的模式切换为灯光或夜间模式或自定义主题,但每当我点击前两个单选按钮时(前两个负责将主题从浅色模式切换到深色模式,反之亦然)我的 ttk.treeview 的宽度被无缘无故地添加了一个。奇怪的是,它不会发生在第三个单选按钮上,负责制作自定义模式。
我尝试为日志的顶层设置一个maxsize,但它会影响 ttk.treeview 本身。为什么会这样?我怎样才能防止这种情况?
我的应用程序的模拟(这只是一个演示,所以我没有编写整个主题代码):
from tkinter import *
from tkinter import colorchooser
from tkinter import ttk
columns = ("Operation", "URL", "File Path", "Status", "Start Date", "End Date")
log_data = [("Download (File)", "https://www.youtube.com", "C:/Users/Mypc/Downloads/youtube.html", "Finished", "2021-03-30 13:15:30", "2021-03-30 13:15:33"),
("Format Fetch", "https://www.youtube.com/watch?v=xxNxqveseyI", "------", "Finished", "2021-03-30 13:15:30", "2021-03-30 13:15:33")]
font_color, bg_color = "black", "white"
root = Tk()
root.configure(bg=bg_color)
root.resizable(False, False)
night_on = IntVar(value=1)
style = ttk.Style()
style.configure("Treeview", rowheight=25, font=('Arial', 10))
style.configure("Treeview.Heading", font=('Arial', 10))
style.configure("TLabel", foreground=font_color, background=bg_color)
style.configure('my.TButton', font=('Helvetica', 20, 'italic'))
style.configure("TRadiobutton", foreground=font_color, background=bg_color, font=('Arial', 10))
font_color_var = StringVar(value=f"Current font color: \t {font_color}")
bg_color_var = StringVar(value=f"Current background color: \t {bg_color}")
log_top = Toplevel(root)
log_top.withdraw()
log_top.resizable(False, False)
log_fr = Frame(log_top)
log_scroll = ttk.Scrollbar(log_fr, orient=VERTICAL)
log_tree = ttk.Treeview(log_fr, selectmode="browse", yscrollcommand=log_scroll.set, height=12, columns=columns)
log_scroll.config(command=log_tree.yview)
def clear_records():
for child in log_tree.get_children():
log_tree.delete(child)
clr_log_btn = ttk.Button(log_top, text="Clear Log", takefocus=False, style="my.TButton", command=clear_records)
log_tree.column("#0", width=0, stretch=NO)
log_tree.column("Operation", width=100, anchor=CENTER)
log_tree.column("URL", width=100, anchor=CENTER)
log_tree.column("File Path", width=100, anchor=CENTER)
log_tree.column("Status", width=80, anchor=CENTER)
log_tree.column("Start Date", width=126, anchor=CENTER)
log_tree.column("End Date", width=126, anchor=CENTER)
for head in columns:
log_tree.heading(head, text=head, anchor=CENTER)
for item_indices, element in enumerate(log_data):
log_tree.insert(parent='', index=0, iid=item_indices, values=element)
log_tree.pack(side=LEFT)
log_scroll.pack(side=RIGHT, fill=Y)
clr_log_btn.pack(side=BOTTOM, fill=X)
log_fr.pack()
log_top.protocol("WM_DELETE_WINDOW", log_top.withdraw)
log_lbl = Label(root, text="Show Log", fg="blue", bg=bg_color, cursor="hand2")
def show_log(event):
if log_top.state() == "withdrawn":
log_top.deiconify()
elif log_top.state() == "normal":
log_top.focus_set()
def settings_win():
settings_top = Toplevel(root, bg=bg_color)
settings_top.resizable(False, False)
def set_night():
global bg_color, font_color
bg_color = "black"
font_color = "white"
settings_top.config(bg=bg_color)
style.configure("TLabel", foreground=font_color, background=bg_color)
style.configure("TRadiobutton", foreground=font_color, background=bg_color)
def set_light():
global bg_color, font_color
bg_color = "white"
font_color = "black"
settings_top.config(bg=bg_color)
style.configure("TLabel", foreground=font_color, background=bg_color)
style.configure("TRadiobutton", foreground=font_color, background=bg_color)
def set_custom():
global font_color, bg_color
color_fr = Toplevel(root, bg=bg_color)
color_fr.resizable(False, False)
current_font_color = ttk.Label(color_fr, textvariable=font_color_var)
current_bg_color = ttk.Label(color_fr, textvariable=bg_color_var)
def change_color(name):
global font_color, bg_color
new_color = colorchooser.askcolor()[1]
if new_color is not None:
if name == "font":
font_color = new_color
font_color_var.set(f"Current font color: \t {font_color}")
style.configure("TLabel", foreground=font_color)
style.configure("TRadiobutton", foreground=font_color)
elif name == "bg":
bg_color = new_color
bg_color_var.set(f"Current background color: \t {bg_color}")
color_fr.config(bg=bg_color)
style.configure("TLabel", background=bg_color)
style.configure("TRadiobutton", background=bg_color)
change_font = ttk.Button(color_fr, text="Change! ", command=lambda: change_color("font"),
takefocus=False)
change_bg = ttk.Button(color_fr, text="Change! ", command=lambda: change_color("bg"), takefocus=False)
current_font_color.grid(row=0, column=0, pady=(10, 0), padx=5)
change_font.grid(row=0, column=1, padx=(0, 7))
current_bg_color.grid(row=1, column=0, pady=(10, 0), padx=5)
change_bg.grid(row=1, column=1, padx=(0, 7))
night_mode = ttk.Radiobutton(settings_top, text="Night Mode", variable=night_on, value=0,
command=set_night, takefocus=False)
light_mode = ttk.Radiobutton(settings_top, text="Light Mode", variable=night_on, value=1,
command=set_light, takefocus=False)
custom_mode = ttk.Radiobutton(settings_top, text="Custom Mode", variable=night_on, value=2,
command=set_custom, takefocus=False)
night_mode.grid(row=0, column=0)
light_mode.grid(row=1, column=0)
custom_mode.grid(row=2, column=0)
log_lbl.bind("<Button-1>", show_log)
log_lbl.pack(side=LEFT, pady=30, padx=30)
settings_btn = ttk.Button(root, text="Open Settings", takefocus=False, command=settings_win)
settings_btn.pack(side=RIGHT, padx=30, pady=30)
root.focus_set()
root.mainloop()