如何在 tkinter 列表框中对齐文本
How to align text in a tkinter Listbox
我想在 tkinter 列表框中对齐文本。我有一个带有 reg 的字典列表。号码、姓名和电子邮件作为每个字典中的键。我遍历了列表并希望三个属性以这样的方式对齐,即这些词之间的距离相等。因此,每一行中的每个单词都必须从与之前/之后行中的单词相同的位置开始。但是由于不同的名称长度,对齐被打乱了。
在上面的代码中,为了简单起见,我刚刚为 4 个学生创建了 4 个词典,但实际上我必须管理 50 多个学生。
除了列表框之外,还有另一种简单的方法来显示此数据,具有上述相同的条件吗?
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()
直接的方法就是用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()
它显示:
您可以试试下面的代码。您必须使用 Monospace 字体 脚本才能工作
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()
您可以使用string formatting
和fixed/monospaced字体:
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']}")
如果您不喜欢 hard-coded 宽度,您可以计算每列的最大宽度:
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']}")
我想在 tkinter 列表框中对齐文本。我有一个带有 reg 的字典列表。号码、姓名和电子邮件作为每个字典中的键。我遍历了列表并希望三个属性以这样的方式对齐,即这些词之间的距离相等。因此,每一行中的每个单词都必须从与之前/之后行中的单词相同的位置开始。但是由于不同的名称长度,对齐被打乱了。 在上面的代码中,为了简单起见,我刚刚为 4 个学生创建了 4 个词典,但实际上我必须管理 50 多个学生。 除了列表框之外,还有另一种简单的方法来显示此数据,具有上述相同的条件吗?
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()
直接的方法就是用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()
它显示:
您可以试试下面的代码。您必须使用 Monospace 字体 脚本才能工作
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()
您可以使用string formatting
和fixed/monospaced字体:
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']}")
如果您不喜欢 hard-coded 宽度,您可以计算每列的最大宽度:
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']}")