简体   繁体   English

如何在 tkinter 列表框中对齐文本

[英]How to align text in a tkinter Listbox

I want to align text within a tkinter listbox.我想在 tkinter 列表框中对齐文本。 I have a list of dictionaries with reg.我有一个带有 reg 的字典列表。 no., name, and email as keys in each dictionary. no.、name 和 email 作为每个字典中的键。 I have looped over the list and want the three attributes to be aligned in such a way, that there is equal distance between these words.我已经遍历了列表,并希望三个属性以这样的方式对齐,即这些词之间的距离相等。 So every word in every row has to start at the same position than the word in the row before / afterwards.因此,每一行中的每个单词都必须以与之前/之后的行中的单词相同的 position 开头。 But due to different name lengths, the alignment is disturbed.但由于名称长度不同,alignment 受到干扰。 In the code above, for simplicity i have just created 4 dictionaries for 4 students, but actually there are more than 50 students that I have to manage.在上面的代码中,为简单起见,我刚刚为 4 个学生创建了 4 个字典,但实际上我必须管理 50 多个学生。 Also is there another simple way to display this data other than the list box, with the same condition stated above?除了列表框之外,还有另一种简单的方法来显示这些数据,条件与上述相同吗?

from tkinter import *

root = Tk()

students_Box = LabelFrame(root,
                    text = 'Registered Students', bd = 4,
                    relief = GROOVE, labelanchor = 'n',
                    font = 'Arial 10 bold', fg = 'navy blue',
                    width = 850, height = 180)
                            
students_Box.grid_propagate(0)
students_Box.pack(pady = 15)

scrollbar = Scrollbar(students_Box)
scrollbar.pack(side = RIGHT, fill = Y)

listbox = Listbox(students_Box, width = 90, bg = 'azure', font = 'TkDefaultFont 11')
listbox.pack(padx = 5, pady = 10)

allStudents = [{'Reg': '2018-MC-01', 'Name': 'Usman Khan', 'Email': '2018mc01@student.uet.edu.pk'},
            {'Reg': '2018-MC-02', 'Name': 'Muhammad Ehtisham Zafar', 'Email': '2018mc02@student.uet.edu.pk'},
            {'Reg': '2018-MC-03', 'Name': 'Ali Khan', 'Email': '2018mc03@student.uet.edu.pk'},
            {'Reg': '2018-MC-04', 'Name': 'Abdullah Akram', 'Email': '2018mc04@student.uet.edu.pk'}]   # A List of Dictionaries

for i in range(len(allStudents)):
        listbox.insert(END, f"{allStudents[i]['Reg']}     {allStudents[i]['Name']}{' '*20}{allStudents[i]['Email']}")

listbox.configure(yscrollcommand = scrollbar.set)
scrollbar.configure(command = listbox.yview)

mainloop()

The direct way is to use ttk.Treeview .The solution under your circumstance(use ljust to fill them):直接的方法是使用ttk.Treeview 。根据您的情况的解决方案(使用ljust填充它们):

from tkinter import *

root = Tk()

students_Box = LabelFrame(root,
                          text='Registered Students', bd=4,
                          relief=GROOVE, labelanchor='n',
                          font='Arial 10 bold', fg='navy blue',
                          width=850, height=180)

students_Box.grid_propagate(0)
students_Box.pack(pady=15)

scrollbar = Scrollbar(students_Box)
scrollbar.pack(side=RIGHT, fill=Y)

listbox = Listbox(students_Box, width=90, bg='azure', font='TkDefaultFont 11')
listbox.pack(padx=5, pady=10)

allStudents = [{'Reg': '2018-MC-01', 'Name': 'Usman Khan', 'Email': '2018mc01@student.uet.edu.pk'},
               {'Reg': '2018-MC-02', 'Name': 'Muhammad Ehtisham Zafar', 'Email': '2018mc02@student.uet.edu.pk'},
               {'Reg': '2018-MC-03', 'Name': 'Ali Khan', 'Email': '2018mc03@student.uet.edu.pk'},
               {'Reg': '2018-MC-04', 'Name': 'Abdullah Akram',
                'Email': '2018mc04@student.uet.edu.pk'}]  # A List of Dictionaries

maxspace = len(max(allStudents, key=lambda x:len(x['Name']))['Name']) + 4 # add 4 spaces.

for i in range(len(allStudents)):
    listbox.insert(END, f"{allStudents[i]['Reg']}     {allStudents[i]['Name'].ljust(maxspace)}{allStudents[i]['Email']}")

listbox.configure(yscrollcommand=scrollbar.set)
scrollbar.configure(command=listbox.yview)

mainloop()

And it shows:它显示: 在此处输入图像描述

You can use string formatting and fixed/monospaced font:您可以使用string formatting和固定/等宽字体:

listbox = Listbox(students_Box, width=90, bg='azure', font='Courier 11') # use a fixed/monospaced font
...
for rec in allStudents:
    listbox.insert(END, f"{rec['Reg']:15}{rec['Name']:30}{rec['Email']}")

If you do not prefer hard-coded widths, you can calculate the maximum width of each column:如果您不喜欢硬编码的宽度,您可以计算每列的最大宽度:

widths = {key:0 for key in allStudents[0]}
for rec in allStudents:
    for key in rec:
        widths[key] = max(widths[key], len(rec[key]))

for rec in allStudents:
    listbox.insert(END, f"{rec['Reg']:{widths['Reg']}}  {rec['Name']:{widths['Name']}}  {rec['Email']}")

You can try the following code.你可以试试下面的代码。 You have to use Monospace Fonts for the script to work您必须使用Monospace Fonts脚本才能工作

from tkinter import *

root = Tk()

students_Box = LabelFrame(root,
                    text = 'Registered Students', bd = 4,
                    relief = GROOVE, labelanchor = 'n',
                    font = 'Arial 10 bold', fg = 'navy blue',
                    width = 850, height = 180)
                            
students_Box.grid_propagate(0)
students_Box.pack(pady = 15)

scrollbar = Scrollbar(students_Box)
scrollbar.pack(side = RIGHT, fill = Y)

listbox = Listbox(students_Box, width = 90, bg = 'azure', font = ('Consolas', 10, ''))#'TkDefaultFont 11')
listbox.pack(padx = 5, pady = 10)

allStudents = [{'Reg': '2018-MC-01', 'Name': 'Usman Khan', 'Email': '2018mc01@student.uet.edu.pk'},
            {'Reg': '2018-MC-02', 'Name': 'Muhammad Ehtisham Zafar', 'Email': '2018mc02@student.uet.edu.pk'},
            {'Reg': '2018-MC-03', 'Name': 'Ali Khan', 'Email': '2018mc03@student.uet.edu.pk'},
            {'Reg': '2018-MC-04', 'Name': 'Abdullah Akram', 'Email': '2018mc04@student.uet.edu.pk'}]   # A List of Dictionaries

MaxRegLength = len(max(allStudents, key=lambda s: len(s['Reg']))['Reg'])
MaxNameLength = len(max(allStudents, key=lambda s: len(s['Name']))['Name'])
print(MaxRegLength, MaxNameLength)
# MaxEmailLength = max(allStudents, key=lambda s: len(s['name']))

for i in range(len(allStudents)):
    listbox.insert(END, 
    '%s         %s          %s'%(allStudents[i]['Reg'].ljust(MaxRegLength), allStudents[i]['Name'].ljust(MaxNameLength), allStudents[i]['Email']))
    # f"{allStudents[i]['Reg'].ljust(MaxRegLength)}       {allStudents[i]['Name'].ljust(MaxNameLength)}       {allStudents[i]['Email']}")

listbox.configure(yscrollcommand = scrollbar.set)
scrollbar.configure(command = listbox.yview)

mainloop()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM