[英]Delete row in tkinter treeview with identified “cell”
我用tkitner制作了一個樹狀視圖,它使您可以通過單擊按鈕在樹狀視圖中識別出一個“單元格”,我使用了tree.identify_region(event.x, event.y) == ' cell'
。
一鍵單擊即可識別“單元格”(我已使用bind
功能<Button-1>
)。 我想制作一個將刪除行(所選行)的函數,但是該函數不起作用。 它沒有顯示任何錯誤。 我認為問題在於,即使選擇了該行,也選擇了“單元格”。
我發布了完整的代碼(即使它很長),因為我認為您需要查看我為完成此操作所做的工作
這是代碼:
from tkinter import *
from tkinter import ttk
import math
from tkinter import messagebox
def edit(event):
def double(event): # funkcija koja kreira celiju kada se klikne dupli klik
try:
if tree.identify_region(event.x, event.y) == 'cell':
# the user clicked on a cell
def ok(event):
"""Change item value."""
tree.set(item, column, entry.get())
entry.destroy()
column = tree.identify_column(event.x) # identify column
item = tree.identify_row(event.y) # identify item
x, y, width, height = tree.bbox(item, column)
value = tree.set(item, column)
elif tree.identify_region(event.x, event.y) == 'heading':
# the user clicked on a heading
def ok(event):
"""Change heading text."""
tree.heading(column, text=entry.get())
entry.destroy()
column = tree.identify_column(event.x) # identify column
# tree.bbox work only with items so we have to get the bbox of the heading differently
x, y, width, _ = tree.bbox(tree.get_children('')[0], column) # get x and width (same as the one of any cell in the column)
# get vertical coordinates (y1, y2)
y2 = y
# get bottom coordinate
while tree.identify_region(event.x, y2) != 'heading':
y2 -= 1
# get top coordinate
y1 = y2
while tree.identify_region(event.x, y1) == 'heading':
y1 -= 1
height = y2 - y1
y = y1
value = tree.heading(column, 'text')
elif tree.identify_region(event.x, event.y) == 'nothing':
column = tree.identify_column(event.x) # identify column
# check whether we are below the last row:
x, y, width, height = tree.bbox(tree.get_children('')[-1], column)
if event.y > y:
def ok(event):
"""Change item value."""
# create item
item = tree.insert("", "end", values=("", ""))
tree.set(item, column, entry.get())
entry.destroy()
y += height
value = ""
else:
return
else:
return
# display the Entry
entry = ttk.Entry(tree) # create edition entry
entry.place(x=x, y=y, width=width, height=height, anchor='nw') # display entry on top of cell
entry.insert(0, value) # put former value in entry
entry.bind('<FocusOut>', ok) #validate when you click on other cell
entry.focus_set()
except IndexError:
Error=messagebox.showinfo("Error!","You have 0 rows. Please add a new row.")
pass
tree.bind('<Button-1>', double) #kreiranje celije za unos i novi red sa duplim klikom
def deleterow(event): # funkcija za brisanje izabranog reda sa delete i backspace dugmicima
try:
SelectedRow= tree.selection()[0]
tree.delete(SelectedRow)
except IndexError:
Error=messagebox.showinfo("Error!","Please seleect the project that you want to delete")
sys.exit() #za resavalje greske
pass
except ValueError:
Error=messagebox.showinfo("Error!","Please seleect the project that you want to delete")
sys.exit() #za resavalje greske
pass
tree.bind("<Delete>", deleterow)
tree.bind("<BackSpace>", deleterow)
myApp = Tk()
myApp.title(" Program ")
myApp.geometry("1900x1000")
tree = ttk.Treeview(myApp, height=20)
tree['show'] = 'headings'
sb = ttk.Scrollbar(myApp, orient="vertical", command=tree.yview)
sb.grid(row=1,column=12,sticky="NS")
tree.configure(yscrollcommand=sb.set)
tree["columns"]=("1","2")
tree.column("1", width=50)
tree.column("2", width=50)
tree.heading("1", text="Project Name")
tree.heading("2", text="Size [m2]")
item = tree.insert("", "end", values=("",))
tree.item(item, tags=item)
tree.bind('<1>', edit)
tree.grid(row=1 ,column=0,pady=5)
myApp.mainloop()
如果我用<Double-Button-1>
標識“單元格”,那么它就起作用了,因為單擊1只是識別行,而不是單元格。
如果我使用<Button-1>
進行單元格識別,您有任何辦法嗎?
這有點困難,因為我對Treeview的經驗很少。 我試圖隔離不同的功能,並且還刪除了許多對於基本理解而言不必要的代碼。 我想我有一個可行的概念,但是我的代碼結構與您的代碼完全不同。 看看您的想法:
from tkinter import *
from tkinter import ttk
def cell(event):
'''Identify cell from mouse position'''
row, col = tree.identify_row(event.y), tree.identify_column(event.x)
pos = tree.bbox(row, col) # Calculate positon of entry
return row, col, pos
def single(event=None):
'''Single click to select row and column'''
global row, col, pos
row, col, pos = cell(event)
print('Select', row, col)
def ok(event=None):
'''Validate entry as at loses focus'''
tree.set(*item, typed.get()) # Set tree cell text
entry.place_forget() # Remove entry without deleting it
def double(event=None):
'''Double click to edit cell'''
global row, col, pos, item
row, col, pos = cell(event)
print('Edit', row, col)
item = row, col # Remember which item you are editing
typed.set(tree.set(row, col)) # Set entry text
x, y, w, h = pos # Place entry on tree
entry.place(x=x, y=y, width=w, height=h, anchor='nw')
entry.focus_set() # Set focus in entry
def deleterow(event):
'''Delete selected row'''
print('delete', len(tree.selection()))
if len(tree.selection()) != 0:
row = tree.selection()[0]
try:
print('deleterow', row)
tree.delete(row)
except:
print('no row selected')
myApp = Tk()
myApp.title(" Program ")
myApp.geometry("600x600+800+50")
tree = ttk.Treeview(myApp, height=20)
tree['show'] = 'headings'
sb = ttk.Scrollbar(myApp, orient="vertical", command=tree.yview)
sb.grid(row=1,column=12,sticky="NS")
tree.configure(yscrollcommand=sb.set)
tree["columns"]=("1","2")
tree.column("1", width=150)
tree.column("2", width=150)
tree.grid(row=1 ,column=0,pady=5)
tree.heading("1", text="Project Name")
tree.heading("2", text="Size [m2]")
item = tree.insert("", "end", values=("Project Alice","500 GB"))
tree.item(item, tags=item)
# Mouse & keyboard bindings
tree.bind('<1>', single)
tree.bind('<Double-Button-1>', double)
tree.bind("<Delete>", deleterow)
# Create entry in global scope
typed = StringVar()
entry = ttk.Entry(tree, textvariable=typed)
entry.bind('<FocusOut>', ok)
myApp.mainloop()
我將控制台打印輸出保留在代碼中,因此更容易看到正在發生的情況。 我使用全局變量來跟蹤重要變量。 我對變量名的選擇可能會更好。
無論如何,使用此代碼,我可以選擇單個或雙擊任何行/列。 刪除行似乎工作正常。 我沒有添加新行的任何功能,但這應該不難。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.