使用Tkinter中的滚动条冻结网格中的标题

时间:2015-12-04 23:56:30

标签: python tkinter header scrollbar

所以我最终决定建立一个GUI,但我感觉很糟糕,我无法在互联网上找到任何东西。
我试图实现的基本上是"冻结窗格" Excel中的选项。 我在this指南之后构建了一个可滚动的标签网格。但是当我滚动时,我想要保留初始网格的标题。 我想过制作一个单独的网格并将标题放在其中,但除了(0,0,0,0) bbox之外我还可以选择其他任何内容(将它们放置正确,因为标题可能很短而条目可能很长!)。

作为bbox的替代方案,我想到了"扩展"标题类似于 title+' '*(len(longest_entry)-len(title)),但如果条目列表很大,那么这似乎非常低效,如果我的条目类似于||||||WWWWWW,由于大小不同,可能看起来不那么漂亮字符。
在这种情况下你能帮助我bbox吗? (我该怎么用呢?)
或者给我完全不同的想法做什么? 非常感谢提前!

很抱歉使用已弃用的代码,但我无法找到合适的代码

1 个答案:

答案 0 :(得分:0)

这是我正在为我的任务列表工作的GUI,其优先级和描述非常有效。输入框和标题位于单独的画布上,因此标题不会滚动,输入框也会滚动。我无法将标题与条目对齐。短期修复是使用碰巧对齐的不同字体。我仍然不知道为什么显式设置宽度不起作用。

import Tkinter as Tk
from Tkinter import StringVar
#-----------------------------------------------------------------------------
# Scroll entry boxes with mouse wheel
#     canvas1, frame1
#
# Header row is on a separate canvas and will not scroll with entry boxes.
#     canvas2, frame2
#
# Could not align header and entries unless different fonts were used.
# Play with variable "font_choice" to see how it works
#-----------------------------------------------------------------------------
# define fonts and other preliminary things

font_choice = 1
if(font_choice == 1): # using same font sizes does not align well
    Label_Font = "Arial 10"
    Entry_Font = "Arial 10"
if(font_choice == 2): # using different font sizes not exactly aligned, but close
    Label_Font = "Arial 9 bold" 
    Entry_Font = "Arial 10"
if(font_choice == 3): # this does not align well
    Label_Font = "Helvetica 10"
    Entry_Font = "Helvetica 10"
if(font_choice == 4): # this aligns pretty well (surprisingly)
    Label_Font = "Helvetica 14"
    Entry_Font = "Helvetica 14"

width_priority = 10
width_time_estimate = 15
width_description_1 = 90

Labels = ["Priority", "Time Est. (mins)", "Description 1"]

Widths = [width_priority, width_time_estimate, width_description_1]

Label_Colors = ["misty rose", "lavender", "lightcoral"]

list_length = 25

canvas_width = 1300
header_height = 25
#------------------------------------------------------------------------------
def populate1(framex):
    global entrys_1
    global entrys_2
    global entrys_3

    label_flag = 0 # 1 or 2 are options, 0 is off

    ijk_col = 0
    if(label_flag == 1):
        Tk.Label(framex, text=Labels[ijk_col]).grid(row=0, column=ijk_col)
    if(label_flag== 2):
        xy1 = Tk.Label(framex, text=Labels[ijk_col], font=Label_Font)
        xy1.grid(row=0, column=ijk_col)
        xy1.config(width=Widths[ijk_col], borderwidth="1", background=Label_Colors[ijk_col])
    entrys_1 = []
    variables_1 = []
    ii = 0
    for row in range(list_length):
        rowx = row + 1
        variables_1.append(StringVar())
        entrys_1.append(Tk.Entry(framex, textvariable=variables_1[ii], font=Entry_Font))
        entrys_1[-1].config(width=Widths[ijk_col], borderwidth="1")
        entrys_1[-1].grid(row=rowx, column=ijk_col)
        entrys_1[-1].config(fg="black", bg=Label_Colors[ijk_col])
        entrys_1[-1].delete(0, Tk.END)
        entrys_1[-1].insert(0, "Placeholder")
        ii += 1

    ijk_col = 1
    if(label_flag == 1):
        Tk.Label(framex, text=Labels[ijk_col]).grid(row=0, column=ijk_col)
    if(label_flag== 2):
        xy2 = Tk.Label(framex, text=Labels[ijk_col], font=Label_Font)
        xy2.grid(row=0, column=ijk_col)
        xy2.config(width=Widths[ijk_col], borderwidth="1", background=Label_Colors[ijk_col])
    entrys_2 = []
    variables_2 = []
    ii = 0
    for row in range(list_length):
        rowx = row + 1
        variables_2.append(StringVar())
        entrys_2.append(Tk.Entry(framex, textvariable=variables_2[ii], font=Entry_Font))
        entrys_2[-1].config(width=Widths[ijk_col], borderwidth="1")
        entrys_2[-1].grid(row=rowx, column=ijk_col)
        entrys_2[-1].config(fg="black", bg=Label_Colors[ijk_col])
        entrys_2[-1].delete(0, Tk.END)
        entrys_2[-1].insert(0, "Placeholder")
        ii += 1

    ijk_col = 2
    if(label_flag == 1):
        Tk.Label(framex, text=Labels[ijk_col]).grid(row=0, column=ijk_col)
    if(label_flag== 2):
        xy3 = Tk.Label(framex, text=Labels[ijk_col], font=Label_Font)
        xy3.grid(row=0, column=ijk_col)
        xy3.config(width=Widths[ijk_col], borderwidth="1", background=Label_Colors[ijk_col])
    entrys_3 = []
    variables_3 = []
    ii = 0
    for row in range(list_length):
        rowx = row + 1
        variables_3.append(StringVar())
        entrys_3.append(Tk.Entry(framex, textvariable=variables_3[ii], font=Entry_Font))
        entrys_3[-1].config(width=Widths[ijk_col], borderwidth="1")
        entrys_3[-1].grid(row=rowx, column=ijk_col)
        entrys_3[-1].config(fg="black", bg=Label_Colors[ijk_col])
        entrys_3[-1].delete(0, Tk.END)
        entrys_3[-1].insert(0, "Placeholder")
        ii += 1

def onFrameConfigure(canvas):
    '''Reset the scroll region to encompass the inner frame'''
    canvas.configure(scrollregion=canvas.bbox("all"))
#-----------------------------------------------------------------------------
root = Tk.Tk()
root.title("StackOverflow_Label_Entry_Align")
#---------------------------------
# set up canvas that scrolls for entries, header on separate canvas that does not scroll

canvas1 = Tk.Canvas(root, borderwidth=0, background="#ffffff", height=400, width=canvas_width)
frame1 = Tk.Frame(canvas1, background="#ffffff")

xscrollbar = Tk.Scrollbar(root, orient=Tk.HORIZONTAL, command=canvas1.xview)
yscrollbar = Tk.Scrollbar(root, orient=Tk.VERTICAL, command=canvas1.yview)

yscrollbar.pack(side=Tk.RIGHT, fill=Tk.Y)
xscrollbar.pack(side=Tk.BOTTOM, fill=Tk.X)

canvas1.configure(xscrollcommand=xscrollbar.set)
canvas1.configure(yscrollcommand=yscrollbar.set)

canvas1.pack(side="bottom", fill="both", expand=True)
canvas1.create_window((4,4), window=frame1, anchor="nw")

frame1.bind("<Configure>", lambda event, canvas=canvas1: onFrameConfigure(canvas))

def _on_mousewheel(event):
    canvas1.yview_scroll(-1*(event.delta/120), "units")
canvas1.configure(yscrollincrement='20') # adjust sensitivity
canvas1.bind_all("<MouseWheel>", _on_mousewheel) # Oakley has a post on this

canvas1.focus_set() # key to making canvas bind to left, right keys
#-----------------------------------------------------------------------------
# set up separate canvas for header row that will not scroll

canvas2 = Tk.Canvas(root, borderwidth=0, background="#ffffff", height=header_height, width=canvas_width)
frame2 = Tk.Frame(canvas2, background="#ffffff")

canvas2.pack(side="top", fill="both", expand=True)
canvas2.create_window((0,0), window=frame2, anchor="nw", height=header_height)

x1 = Tk.Label(frame2, text=Labels[0], font=Label_Font)
x1.grid(row=0, column=0)
x1.config(width=Widths[0], borderwidth="1", background=Label_Colors[0])

x2 = Tk.Label(frame2, text=Labels[1], font=Label_Font)
x2.grid(row=0, column=1)
x2.config(width=Widths[1], borderwidth="1", background=Label_Colors[1])

x3 = Tk.Label(frame2, text=Labels[2], font=Label_Font)
x3.grid(row=0, column=2)
x3.config(width=Widths[2], borderwidth="1", background=Label_Colors[2])
#-----------------------------------------------------------------------------
populate1(frame1) # add entry boxes
#-----------------------------------------------------------------------------
root.mainloop()
#-----------------------------------------------------------------------------