用Tkinter中的滚动条在网格中冻结标题 [英] Freezing the header in a grid with a scrollbar in Tkinter

查看:142
本文介绍了用Tkinter中的滚动条在网格中冻结标题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我终于决定建立一个图形用户界面,但我被卡住了,我在互联网上找不到任何东西。

我想要实现的基本上是冻结窗格选项从Excel。
我在这个指南。但是当我滚动时,我希望初始网格的标题保持不变。
我曾想过创建一个单独的网格并将头部放在其中,但除了(0,0,0,0)之外, bbox (将它们放置正确,因为标题可能很短而条目可能很长!)。

作为 bbox 的替代方式,我曾想过用$ b $ b title +''*(len(longest_entry)-len(title)),但是如果条目列表很大并且可能看起来不那么漂亮如果由于字符的大小不同,我的输入类似 |||||| WWWWWW 。 >
在这种情况下,你可以帮我用 bbox 吗? (我应该怎么使用它?)

或者给我完全不同的想法做什么?

非常感谢提前!



对于使用已弃用的标签抱歉标题,但我找不到合适的标签

解决方案

这是我工作的GUI为我的任务列表优先级和说明,运作良好。输入框和标题位于单独的画布上,以便标题不会滚动并且输入框会显示。我无法将标题与条目对齐。短期修复是使用发生对齐的不同字体。

 从Tkinter导入Tkinter作为Tk 
导入StringVar
#--------------------------------------------- --------------------------------
#使用鼠标滚轮滚动输入框
#canvas1, frame1

#标题行位于单独的画布上,不会使用输入框进行滚动。
#canvas2,frame2

#除非使用不同的字体,否则无法对齐标题和条目。
#与变量font_choice一起玩,看看它是如何工作的
#----------------------------- ------------------------------------------------
#定义字体和其他初步的东西

font_choice = 1
if(font_choice == 1):#使用相同的字体大小不能很好地对齐
Label_Font =Arial 10
Entry_Font =Arial 10
if(font_choice == 2):#使用不同的字体大小不完全对齐,但关闭
Label_Font =Arial 9粗体
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):#这个对齐很好(令人惊讶的)
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_estima te,width_description_1]

Label_Colors = [朦胧玫瑰,薰衣草,lightcoral]

list_length = 25

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

label_flag = 0#1或2为期权,0为止

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
(list_length):
rowx = row + 1
variables_1.append(StringVar())
e ntrys_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,占位符)
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

rowx = row + 1
variables_2.append(StringVar())
entrys_2.append(Tk.Entry(fra mex,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,占位符)
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 ,row = range(row_length):
entropy_3 = []
variables_3 = []
ii = 0

rowx = row + 1
variables_3.append(StringVar())
entrys_3.append(Tk.Entry(framex,textvariable = variable _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):
'''将滚动区域重置为包含内部框架'''
canvas.configure(scrollregion = canvas.bbox(all))
#------------------- -------------------------------------------------- --------
root = Tk.Tk()
root.title(StackOverflow_Label_Entry_Align)
#-------------- -------------------
#设置滚动条目的画布,不滚动的单独画布上的标题

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

xscrollbar = Tk.S crollbar(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。设置)
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') #调整灵敏度
canvas1.bind_all(< MouseWheel>,_on_mousewheel)#Oakley在这个

canvas1.focus_set()#键上有一个帖子,使画布绑定到左侧,右侧键
#-------------------------------------------- ------------------------------- -
#为不滚动的标题行设置单独的画布

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])$ ​​b
$ b 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])
#---- -------------------------------------------------- -----------------------
populat e1(frame1)#添加输入框
#------------------------------------- ----------------------------------------
root.mainloop()
#---------------------------------------------- -------------------------------


So I finally decided to build a GUI, but I'm stuck bad, and I can't find anything on the internet.
What I'm trying to acomplish is basically the "freeze panes" option from Excel. I have build a scrollable grid of labels following this guide. But I want the header of the initial grid to stay when I scroll. I have thought of making a separate grid and place the header in it, but I can't anything other than (0,0,0,0) from bbox (to place them right, because the header might be short while the entries might be long!).

As an alternative to bbox I have thought of "expanding" the titles with something like
title+' '*(len(longest_entry)-len(title)), but that seems highly inefficient if the entry list is huge and probably won't look as pretty if my entry is something like |||||| or WWWWWW due to different size of the characters.
Can you help me with bbox in this case? (what should I use it on?)
Or give me totally different ideas of what to do?
Many thanks in advance!

Sorry for using the deprecated tag , but I couldn't find an appropiate tag

解决方案

This is a GUI I'm working on for my tasks list with priority and description that works pretty well. The entry boxes and headers are on separate canvases so that the header will not scroll and the entry boxes will. I had trouble aligning the headers with the entries. The short term fix was to use different fonts that happen to align. I still don't know why explicitly setting widths did not work.

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()
#-----------------------------------------------------------------------------

这篇关于用Tkinter中的滚动条在网格中冻结标题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆