微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

点击 ttk.Radiobutton 后 ttk.Treeview 的宽度增加

如何解决点击 ttk.Radiobutton 后 ttk.Treeview 的宽度增加

我一直在使用 tkinter 和 tkinter.ttk 在 python 中制作这个下载器应用程序,并在应用程序中添加一个最近的功能,供用户查看程序执行的先前操作的日志。它工作正常,但是,我最近发现了一个错误

我有一个设置按钮,可以创建另一个顶级,然后您可以管理认目录,并使用三个 ttk.Radiobuttons 将应用程序的模式更改为灯光或夜间模式或自定义主题但是每当我点击前两个单选按钮(前两个负责将主题从亮模式切换到暗模式,反之亦然)时,我的 ttk.treeview 的宽度会无缘无故地增加一个。奇怪的是第三个radiobutton没有发生,负责制作自定义模式。

我尝试为日志的顶层设置 ma​​xsize,但它影响了 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","------","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",10))
style.configure("TLabel",foreground=font_color,background=bg_color)
style.configure('my.TButton',font=('Helvetica',20,'italic'))
style.configure("Tradiobutton",background=bg_color,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",anchor=CENTER)
log_tree.column("File Path",anchor=CENTER)
log_tree.column("Status",width=80,anchor=CENTER)
log_tree.column("Start Date",width=126,anchor=CENTER)
log_tree.column("End Date",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",background=bg_color)
        style.configure("Tradiobutton",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",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,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,padx=5)
        change_bg.grid(row=1,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",value=1,command=set_light,takefocus=False)
    custom_mode = ttk.Radiobutton(settings_top,text="Custom Mode",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",command=settings_win)
settings_btn.pack(side=RIGHT,padx=30,pady=30)
root.focus_set()
root.mainloop()

解决方法

我想我找到了解决您问题的方法。首先,我缩小了您的代码以使其更易于调试:

import tkinter as tk
from tkinter import ttk

columns = ("1","2","3")
font_color,bg_color = "black","white"

def change_theme():
    global bg_color,font_color
    # Switches the values of `bg_color` and `font_color`
    bg_color,font_color = font_color,bg_color
    root.config(bg=bg_color)
    style.configure("TLabel",fg=font_color,bg=bg_color)


root = tk.Tk()

style = ttk.Style()

tree = ttk.Treeview(root,columns=columns)
tree.pack()

button = tk.Button(root,text="Click me",command=change_theme)
button.pack()

root.mainloop()

再次查看您的代码后,我注意到您的 stretch=NOstretch=False 标题的 #0 相同。我决定像这样将它应用到所有标题:

tree.column("#0",stretch=False)
for column_name in columns:
    tree.column(column_name,stretch=False)

它解决了你的问题。查看 ttk.TreeViewthis 文档后,我注意到它对拉伸参数的说明:“如果此选项为 True,则在调整小部件大小时将调整列的宽度。默认设置是 1。” 由此我得出结论,由于某种原因,style.configure("TLabel",...) 更改了树视图的宽度,从而触发了所有列的大小调整。

我对 TreeViewStyles 了解不够,无法告诉您为什么会发生这种情况,但如果有人知道他们可以编辑我的答案。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。