从树视图中删除选定的项目,同时从列表中删除

时间:2017-04-23 13:21:01

标签: python list tkinter treeview

我创建了一个简单的任务GUI应用程序。除了将项目添加到树视图外,我还将它们添加到Task对象列表中。我想从树视图中删除所有选定的项目,同时从列表(self.tasks)中删除。

我只能从树视图中删除一个所选项目,我不知道如何删除多个所选项目。此外,我不知道如何查找和删除我所拥有的列表中的所选项目。

这是我到目前为止所做的:

#!usr/bin/python3

# Todo.py
# GUI program to manage to-do tasks

from tkinter import *
from tkinter import ttk

class Task:

    def __init__(self, subject=None, priority=None):
        self.subject = subject
        self.priority = priority


class Todo(Frame):

    def __init__(self, master):
        Frame.__init__(self, master)
        self.master = master
        self.master.resizable(width=False, height=False)
        self.master.title('Todo')
        self.master.geometry('237x306')
        self.create_widgets()
        self.tasks = []

    def create_widgets(self):
        self.search_frame = Frame(self.master)
        self.search_frame.grid(row=0)

        self.treeview_frame = Frame(self.master)
        self.treeview_frame.grid(row=1)

        self.buttons_frame = Frame(self.master)
        self.buttons_frame.grid(row=2)

        self.search_text = Entry(self.search_frame,
                                 width=29)
        self.search_text.grid(row=0)

        self.treeview = ttk.Treeview(self.treeview_frame,
                                     height=12,
                                     columns=('Subject', 'Priority'))
        self.treeview.grid(row=0)
        self.treeview.column('#0', minwidth=0, width=30, stretch=NO)
        self.treeview.heading('#0', text="#")
        self.treeview.column('Subject', minwidth=0, width=147, stretch=NO)
        self.treeview.heading('Subject', text='Subject')
        self.treeview.column('Priority', minwidth=0, width=57, stretch=NO)
        self.treeview.heading('Priority', text='Priority')
        self.i = 0

        self.add_button = Button(self.buttons_frame,
                                 text='Add',
                                 command=self.add_item)
        self.add_button.grid(row=0, column=0)

        self.remove_button = Button(self.buttons_frame,
                                 text='Remove',
                                 command=self.remove_item)

        self.remove_button.grid(row=0, column=1)

        self.edit_button = Button(self.buttons_frame,
                                  text='Edit',
                                  command=self.edit_item)
        self.edit_button.grid(row=0, column=2)

        self.save_button = Button(self.buttons_frame,
                                  text='Save',
                                  command=self.save_item)
        self.save_button.grid(row=0, column=3)

    def create_item_dialog(self):
        self.item_dialog = Toplevel(self.master)
        self.item_dialog.geometry('202x197')

        self.item_dialog_text_frame = Frame(self.item_dialog)
        self.item_dialog_text_frame.grid(row=0, sticky=W)

        self.item_dialog_combobox_frame = Frame(self.item_dialog)
        self.item_dialog_combobox_frame.grid(row=1, sticky=W)

        self.item_dialog_another_frame = Frame(self.item_dialog)
        self.item_dialog_another_frame.grid(row=2)

        self.item_dialog_buttons_frame = Frame(self.item_dialog)
        self.item_dialog_buttons_frame.grid(row=3)

        self.subject_label = Label(self.item_dialog_text_frame,
                                   text='Subject:')
        self.subject_label.grid(row=0, sticky=W)

        self.subject_text = Text(self.item_dialog_text_frame,
                                 width=28,
                                 height=9)
        self.subject_text.grid(row=1)

        self.priority_label = Label(self.item_dialog_combobox_frame,
                                   text='Priority:')

        self.priority_label.grid(row=0, column=0, sticky=W)

        self.priority_combobox = ttk.Combobox(self.item_dialog_combobox_frame,
                                              width=17)
        self.priority_combobox.grid(row=0, column=1)
        self.priority_combobox['values'] = ('High', 'Medium', 'Low')

        self.item_dialog_ok_button = Button(self.item_dialog_buttons_frame,
                                            width=9,
                                            text='OK',
                                            command=self.add)
        self.item_dialog_ok_button.grid(row=0, column=0)

        self.item_dialog_cancel_button = Button(self.item_dialog_buttons_frame,
                                                width=9,
                                                text='Cancel',
                                                command = self.close_item_dialog)
        self.item_dialog_cancel_button.grid(row=0, column=1)


        self.item_dialog.wait_window()

    def close_item_dialog(self):
        self.item_dialog.destroy()

    def add_item(self):
        self.create_item_dialog()

    def add(self):
        t = Task(self.subject_text.get('1.0', '1.0 lineend'), self.priority_combobox.get())

        self.treeview.insert('', END, text=str(self.i), values=(t.subject, t.priority))
        self.i = self.i + 1
        self.tasks.append(t)

        self.close_item_dialog()

    def remove_item(self):
        selected_item = self.treeview.selection()[0]
        self.treeview.delete(selected_item)

    def edit_item(self):
        pass

    def save_item(self):
        pass

def main():
    root = Tk()
    Todo(root)
    root.mainloop()

if __name__ == '__main__':
    main()

1 个答案:

答案 0 :(得分:2)

1。删除所有选定的项目

树视图的selection()方法返回所选项目的列表。但是在remove_item()中你编码了这一行:

selected_item = self.treeview.selection()[0]

这意味着您只对选定项目列表中的第一个选定项目感兴趣。

如果您考虑这些信息,可以通过如下修改remove_item()来实现目标:

def remove_item(self):
   selected_items = self.treeview.selection()        
   for selected_item in selected_items:          
      self.treeview.delete(selected_item)

2。更新任务列表

我想你想在用户选择并删除一个项目(或一组项目)时更新self.tasks []。

您可以在上面提到的remove_item()函数中执行此操作。

为此,请注意您添加到self.treeview的项目是遵循此表单的词典:

{'open': 0, 'tags': '', 'image': '', 'values': ['cpp', 'Medium'], 'text': '1'}

对您的案例有用的字典的关键是value,因为它允许我们将它与Task()类的每个实例进行比较。

要访问该密钥的值,您必须运行此密钥:self.treeview.item(selected_item)['values']

然后,您会得到一个与Task()实例的字典对应的列表。

因此,您必须将Task()实例(self.tasks[some_index])与上述密钥的值进行比较。

可能是代码更好理解:

 def remove_item(self):
        selected_items = self.treeview.selection()
        for selected_item in selected_items:  
           # Updating selfs.tasks[] through this loop            
           for i in range(len(self.tasks)):
               if self.tasks[i].subject == self.treeview.item(selected_item)['values'][0]:
                   self.tasks.pop(i) # Remove the corresponding item
                   # Make sure the list is updated:
                   print('length: {}'.format(len(self.tasks)))
                   break          
           self.treeview.delete(selected_item)

演示

让我们插入以下7个项目:

enter image description here

我选择其中两个来删除它们。终端上的输出显示列表已更新:

enter image description here