Удалить строку в tkinter treeview с идентифицированной «ячейкой» - PullRequest
0 голосов
/ 27 мая 2018

Я сделал древовидное представление с помощью 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>, то это работает, потому что одним щелчком я просто идентифицирую строку,не клетка.

Есть ли способ сделать это, если я использую <Button-1> для идентификации ячейки?

1 Ответ

0 голосов
/ 27 мая 2018

Это было немного сложно, так как у меня мало опыта с 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()

Я сохранил распечатки консоли в коде, чтобы было легче увидеть, что происходит.Я использую глобальные переменные, чтобы отслеживать важные переменные.Мой выбор имен переменных мог бы быть лучше ...

В любом случае, с помощью этого кода я могу выбрать любую строку / столбец с одиночным или двойным щелчком мыши.Удалить строку, кажется, работает просто отлично.У меня нет никакой функции для добавления новых строк, но это не должно быть сложно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...