如何解决在Tkinter树视图中动态添加列
该程序应该动态添加列,以便在按下相应按钮时显示更多数据。可以按不同的顺序按下按钮,这会影响下一列/标题的外观。正如您在示例程序中看到的那样,标头未正确更新。表中仅显示最后一个。如果项目(选定的行和列)已经有数据,则应对其进行更新,但是当前数据仅添加到新列中,因此问题之一是如何更新由选定的行和标题引用的项目。删除行时,所有空列都应删除。 我试图通过连接元组来更新列,但不知道如何处理标头。 任何建议都非常感谢。
from random import randint
from tkinter import *
from tkinter.ttk import Treeview
def get_window():
root = Tk()
root.resizable(width=True,height=True)
root.geometry("823x458")
root.title("PsControl")
return root
def get_top_frame(root):
frame = Frame(root)
frame.name = 'top_frame'
frame.root = root
frame.pack(side=TOP,expand=False,fill=X)
button1 = Button(frame,text="Add Row",command=lambda: tv.insert('','end',text="hostname"))
button1.grid(row=0,column=1)
button1 = Button(frame,text="Add Cow 1",command=lambda: tv_insert("H1",randint(1,100)))
button1.grid(row=0,column=2)
button2 = Button(frame,text="Add Cow 2",command=lambda: tv_insert("H2",100)))
button2.grid(row=0,column=3)
button3 = Button(frame,text="Add Cow 3",command=lambda: tv_insert("H3",100)))
button3.grid(row=0,column=4)
button4 = Button(frame,text="Add Cow 20",command=lambda: tv_insert("H4",100)))
button4.grid(row=0,column=5)
button5 = Button(frame,text="Delete row",command=lambda: tv.delete(tv.selection()))
button5.grid(row=0,column=6)
def get_bottom_frame(root):
global tv
frame = Frame(root,highlightbackground='#3E4149',highlightthickness=1,borderwidth=2)
frame.name = 'bottom_frame'
frame.root = root
h = Scrollbar(root,orient='horizontal')
h.pack(side=BOTTOM,fill=X)
v = Scrollbar(root)
v.pack(side=RIGHT,fill=Y)
frame.pack(side=BOTTOM,expand=True,fill=BOTH)
frame.config(background='#FFFFFF')
tv = Treeview(frame,xscrollcommand=h.set,yscrollcommand=v.set)
tv.column("#0",width=135,minwidth=35,stretch=NO)
tv.heading("#0",text='Host',anchor='w')
tv.pack(expand=True,fill='both')
h.config(command=tv.xview)
v.config(command=tv.yview)
def tv_insert(heading,insert_data):
selection = tv.selection()
columns = tv["columns"]
if columns == '':
tv["columns"] = (heading,)
tv.column(heading,stretch=NO)
tv.heading(heading,text=heading,anchor='w')
tv.item(selection,values=insert_data)
else:
new_col = columns + (heading,)
tv["columns"] = new_col
tv.heading(heading,anchor='w')
data = tv.item(selection,"values")
if data == '':
tv.item(selection,values=insert_data)
else:
new_data = data + (insert_data,)
tv.item(selection,values=new_data)
def delete_row():
selection = tv.selection()
tv.delete(selection)
root = get_window()
get_top_frame(root)
get_bottom_frame(root)
root.mainloop()
感谢@ acw1668回答,这里的代码可以按预期完成工作。欢迎提出任何改进建议。
def tv_insert(heading,insert_data):
selection = tv.selection()
columns = tv["columns"]
if columns == '': # if no columns,create column,heading and item.
tv["columns"] = (heading,values=(insert_data,))
else:
headings = [tv.heading(col) for col in columns] # save current headings
if heading not in columns:
new_col = columns + (heading,)
tv["columns"] = new_col
# restore previous headings
for h in headings:
tv.heading(h['text'],text=h['text'],anchor=h['anchor'])
# set new heading
tv.heading(heading,anchor='w')
# add data/item with with size of the columns
len_col = len(new_col)
data = ['' for _ in range(len_col)] # Create an empty list
data[len_col - 1] = insert_data # Update the next
tv.item(selection,values=tuple(data))
else:
data = tv.item(selection,"values")
# if heading exist but no item on the the selected row
if data == '':
data = ['' for _ in range(len(headings))]
index = columns.index(heading)
data[index] = insert_data
tv.item(selection,values=tuple(data))
else:
data = list(data)
if len(data) < len(columns):
new_data = ['' for _ in range(len(columns))]
for i,d in enumerate(data):
new_data[i] = d
index = columns.index(heading)
new_data[index] = insert_data
tv.item(selection,values=tuple(new_data))
else:
index = columns.index(heading)
data[index] = insert_data
tv.item(selection,values=tuple(data))
解决方法
由于您已将{em> new 列分配给`router.post("/updateUser",[
//first step
body("slide").not().isEmpty().withMessage('please provide slide number.'),body("birthDate").if(body('slide').custom((value,{
req
}) => value == 0)).not().isEmpty().withMessage('BirthDate is required.'),body("address").if(body('slide').custom((value,{
req
}) => value == 0)).not().isEmpty().withMessage('address is required.'),body("state").if(body('slide').custom((value,{
req
}) => value == 0)).not().isEmpty().withMessage('state is required.'),body("postal_code").if(body('slide').custom((value,{
req
}) => value == 0)).not().isEmpty().withMessage('postal code is required.'),//second step
body("interests").if(body('slide').custom((value,{
req
}) => value == 1)).isArray({
min: 1
}).withMessage('at least one interests is required.'),//third step
body("home").if(body('slide').custom((value,{
req
}) => value == 2)).not().isEmpty().withMessage('homeOwner is required.'),//four step
body("driveVehicle").if(body('slide').custom((value,{
req
}) => value == 3)).not().isEmpty().withMessage('driveVehicle is required.'),//fifth step
body("vehicleDetails.model").if(body('slide').custom((value,{
req
}) => value == 4)).not().isEmpty().withMessage('vehicle model is required.'),body("vehicleDetails.mileage").if(body('slide').custom((value,{
req
}) => value == 4)).not().isEmpty().withMessage('vehicle mileage required.')
],async function (req,res,next) {`
,因此标题信息将丢失。您应在分配 new 列之前保存当前的标题信息,并在之后进行还原:
tv
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。