Python 在Tkinter树视图中动态添加列
程序应该动态添加列,以便在按下相应按钮时显示更多数据。可以按不同的顺序按下按钮,这会影响下一列/标题的外观。正如您在示例程序中所看到的,标题没有正确更新。表中仅显示最后一个。如果项目(所选行和列)已包含数据,则应更新该项目,但当前仅在新列中添加数据,因此问题之一是如何更新所选行和标题引用的项目。删除行时,应删除所有空列。 我试图通过连接元组来更新列,但不知道如何处理标题。 非常感谢您的任何建议Python 在Tkinter树视图中动态添加列,python,tkinter,treeview,Python,Tkinter,Treeview,程序应该动态添加列,以便在按下相应按钮时显示更多数据。可以按不同的顺序按下按钮,这会影响下一列/标题的外观。正如您在示例程序中所看到的,标题没有正确更新。表中仅显示最后一个。如果项目(所选行和列)已包含数据,则应更新该项目,但当前仅在新列中添加数据,因此问题之一是如何更新所选行和标题引用的项目。删除行时,应删除所有空列。 我试图通过连接元组来更新列,但不知道如何处理标题。 非常感谢您的任何建议 from random import randint from tkinter import * fr
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", randint(1, 100)))
button2.grid(row=0, column=3)
button3 = Button(frame, text="Add Cow 3", command=lambda: tv_insert("H3", randint(1, 100)))
button3.grid(row=0, column=4)
button4 = Button(frame, text="Add Cow 20", command=lambda: tv_insert("H4", randint(1, 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, width=135, minwidth=35, 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, text=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,)
tv.column(heading, width=135, minwidth=35, stretch=NO)
tv.heading(heading, text=heading, anchor='w')
tv.item(selection, 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, text=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))
def tv_插入(标题,插入数据):
selection=tv.selection()
columns=tv[“columns”]
如果列=“”:#如果没有列,则创建列、标题和项目。
电视[“列”]=(标题,)
tv.列(标题,宽度=135,最小宽度=35,拉伸=NO)
tv.heading(heading,text=heading,anchor='w')
tv.item(选择,值=(插入数据)
其他:
标题=[列中列的电视标题(列)]#保存当前标题
如果标题不在列中:
新列=列+(标题,)
tv[“列”]=新列
#恢复以前的标题
对于标题中的h:
标题(h['text'],text=h['text'],anchor=h['anchor'])
#设置新标题
tv.heading(heading,text=heading,anchor='w')
#添加具有列大小的数据/项
len_col=len(新的_col)
数据=[''用于范围内的(len_col)]#创建一个空列表
数据[len_col-1]=插入数据#更新下一个
tv.item(选择,值=元组(数据))
其他:
数据=电视项目(选择,“值”)
#如果标题存在,但选定行上没有项目
如果数据=“”:
数据=[''表示范围内的uuu(标题))]
索引=列。索引(标题)
数据[索引]=插入数据
tv.item(选择,值=元组(数据))
其他:
数据=列表(数据)
如果len(数据)
由于您已将新列分配给tv
,因此标题信息将丢失。在指定新列之前,应保存当前标题信息,并在以下操作之后恢复这些信息:
def tv_插入(标题,插入数据):
selection=tv.selection()
columns=tv[“columns”]
如果列=“”:
电视[“列”]=(标题,)
tv.列(标题,宽度=135,最小宽度=35,拉伸=NO)
tv.heading(heading,text=heading,anchor='w')
tv.item(选择,值=插入数据)
其他:
标题=[列中列的电视标题(列)]#保存当前标题
新列=列+(标题,)
tv[“列”]=新列
#恢复以前的标题
对于标题中的h:
标题(h['text'],text=h['text'],anchor=h['anchor'])
#设置新标题
tv.heading(heading,text=heading,anchor='w')
数据=电视项目(选择,“值”)
如果数据=“”:
tv.item(选择,值=插入数据)
其他:
新数据=数据+(插入数据)
tv.item(选择,值=新数据)
谢谢!这正是我要找的。我已经做了一些修改,以涵盖更多的情况,我正在分享工作正常的代码。如果项为空,程序将创建一个大小为len(columns)的空字符串列表,然后更新元素(而不是追加)并将其另存为tuple。如果该项存在,则将其写入空字符串的e列表中,然后更新该元素。代码可以改进,但一般来说,程序会按预期执行。