Python Tkinter-删除选定的列表框项目

时间:2018-11-01 19:01:25

标签: python tkinter listbox

我需要能够突出显示给定列表框中的一个或多个项目并将其删除。我在这里查看了其他人的问题,但是由于某些原因,当我尝试删除项目时,什么也没有发生。

下面是我正在使用的代码。任何人都可以看看并帮助我吗?

import tkinter

class Remove_Button_Widget():

    def __init__(self):
        self.Remove_Button = tkinter.Button(master, text= "Remove", height = 2, width = 6, command =lambda :remove_button().remove_functionality(Robot_Files_Found_Widgets().ROBOT_FILE_LIST))
        self.Remove_Button.place(x=362,y=350)

class Robot_Files_Found_Widgets():


    def __init__(self):
        self.Robot_Files_Ran_Frame = tkinter.Frame(master)
        self.Robot_Files_Ran_Frame.place(bordermode=tkinter.INSIDE, height=30, width=200, y=250, x=35)

        self.Display_Robot_Files_Frame = tkinter.Frame(master, borderwidth=1, highlightthickness=1,
                                              highlightbackground="black", highlightcolor="black")
        self.Display_Robot_Files_Frame.place(bordermode=tkinter.INSIDE, height=200, width=300, y=285, x=50)
        self.ROBOT_FILE_LIST = tkinter.Listbox(self.Display_Robot_Files_Frame,selectmode=tkinter.MULTIPLE)
        self.ROBOT_FILE_LIST.place(bordermode=tkinter.INSIDE, height=196, width=296)

        self.Scroll_Bar_x = tkinter.Scrollbar(self.ROBOT_FILE_LIST, orient=tkinter.HORIZONTAL)
        self.Scroll_Bar_x.config(command=self.ROBOT_FILE_LIST.xview)
        self.Scroll_Bar_x.pack(fill=tkinter.X, side=tkinter.BOTTOM)
        self.ROBOT_FILE_LIST.config(xscrollcommand=self.Scroll_Bar_x.set)
        self.Scroll_Bar_y = tkinter.Scrollbar(self.ROBOT_FILE_LIST, orient=tkinter.VERTICAL)
        self.Scroll_Bar_y.config(command=self.ROBOT_FILE_LIST.yview)
        self.Scroll_Bar_y.pack(fill=tkinter.Y, side=tkinter.RIGHT)
        self.ROBOT_FILE_LIST.config(yscrollcommand=self.Scroll_Bar_y.set)
        list = []
        for x in range(0,15):
            list.append(x)
        for y in list:
            self.ROBOT_FILE_LIST.insert(0,y)

class remove_button():

    def remove_functionality(self, ROBOT_FILE_LIST):
        sel = ROBOT_FILE_LIST.curselection()
        # iterate over sel, deleting each item
        for index in sel:
            ROBOT_FILE_LIST.delete(index)

if __name__ == "__main__":


    master = tkinter.Tk()
    master.title("Test Runner")
    master.geometry("750x500")
    master.resizable(width=False, height=False)
    Robot_Files_Found_Widgets()
    Remove_Button_Widget()
    master.mainloop()

2 个答案:

答案 0 :(得分:3)

您的按钮不起作用的主要原因是您如何构建Lambda。因为您每次按下按钮都在调用该类,所以您实际上并没有在编辑用于构建GUI的该类的第一个实例。您需要保存对类实例的引用才能使其正常工作。我看到您应该避免的另一个问题是调用列表list。不要将变量命名为内置方法。这会破坏代码中的内容。

我认为您不应建立太多的课程。您在此处的所有功能都可以内置到一个类中。也就是说,在删除索引选择时还需要reversed(),这样就不会跳过索引。

import tkinter as tk


class Example(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.title("Test Runner")
        self.geometry("750x500")
        self.resizable(width=False, height=False)
        self.robot_files_ran_frame = tk.Frame(self)
        self.robot_files_ran_frame.place(bordermode=tk.INSIDE, height=30, width=200, y=250, x=35)

        self.display_robot_files_frame = tk.Frame(self, borderwidth=1, highlightthickness=1,
                                              highlightbackground="black", highlightcolor="black")
        self.display_robot_files_frame.place(bordermode=tk.INSIDE, height=200, width=300, y=285, x=50)
        self.robot_file_list = tk.Listbox(self.display_robot_files_frame,selectmode=tk.MULTIPLE)
        self.robot_file_list.place(bordermode=tk.INSIDE, height=196, width=296)

        self.scroll_bar_x = tk.Scrollbar(self.robot_file_list, orient=tk.HORIZONTAL)
        self.scroll_bar_x.config(command=self.robot_file_list.xview)
        self.scroll_bar_x.pack(fill=tk.X, side=tk.BOTTOM)
        self.robot_file_list.config(xscrollcommand=self.scroll_bar_x.set)
        self.scroll_bar_y = tk.Scrollbar(self.robot_file_list, orient=tk.VERTICAL)
        self.scroll_bar_y.config(command=self.robot_file_list.yview)
        self.scroll_bar_y.pack(fill=tk.Y, side=tk.RIGHT)
        self.robot_file_list.config(yscrollcommand=self.scroll_bar_y.set)
        some_list = []

        for x in range(0,15):
            some_list.append(x)

        for y in some_list:
            self.robot_file_list.insert(0, y)

        self.remove_button = tk.Button(self, text= "Remove", height=2, width=6, command=self.remove_functionality)
        self.remove_button.place(x=362, y=350)

    def remove_functionality(self):
        sel = self.robot_file_list.curselection()
        # added reversed here so index deletion work for multiple selections.
        for index in reversed(sel):
            self.robot_file_list.delete(index)

if __name__ == "__main__":
    Example().mainloop()

只是为了纠正原始问题而不重新编写整个代码,您需要保存对列表框的引用,并将其传递给按钮以获取变量。

这是一个使用您的代码并在类之间传递保存的变量的示例。

import tkinter


class Remove_Button_Widget():
    def __init__(self, var1):
        variable_to_pass = var1
        self.Remove_Button = tkinter.Button(master, text="Remove", height=2, width=6, command=lambda :remove_button().remove_functionality(variable_to_pass))
        self.Remove_Button.place(x=362,y=350)


class Robot_Files_Found_Widgets():
    def __init__(self):
        self.Robot_Files_Ran_Frame = tkinter.Frame(master)
        self.Robot_Files_Ran_Frame.place(bordermode = tkinter.INSIDE, height=30, width=200, y=250, x=35)
        self.Display_Robot_Files_Frame = tkinter.Frame(master, borderwidth=1, highlightthickness=1,
                                              highlightbackground="black", highlightcolor="black")
        self.Display_Robot_Files_Frame.place(bordermode = tkinter.INSIDE, height=200, width=300, y=285, x=50)
        self.ROBOT_FILE_LIST = tkinter.Listbox(self.Display_Robot_Files_Frame,selectmode = tkinter.MULTIPLE)
        self.ROBOT_FILE_LIST.place(bordermode = tkinter.INSIDE, height=196, width=296)

        self.Scroll_Bar_x = tkinter.Scrollbar(self.ROBOT_FILE_LIST, orient = tkinter.HORIZONTAL)
        self.Scroll_Bar_x.config(command=self.ROBOT_FILE_LIST.xview)
        self.Scroll_Bar_x.pack(fill = tkinter.X, side = tkinter.BOTTOM)
        self.ROBOT_FILE_LIST.config(xscrollcommand=self.Scroll_Bar_x.set)
        self.Scroll_Bar_y = tkinter.Scrollbar(self.ROBOT_FILE_LIST, orient = tkinter.VERTICAL)
        self.Scroll_Bar_y.config(command=self.ROBOT_FILE_LIST.yview)
        self.Scroll_Bar_y.pack(fill = tkinter.Y, side = tkinter.RIGHT)
        self.ROBOT_FILE_LIST.config(yscrollcommand=self.Scroll_Bar_y.set)
        some_list = []
        for x in range(0,15):
            some_list.append(x)
        for y in some_list:
            self.ROBOT_FILE_LIST.insert(0, y)
        Remove_Button_Widget(self.ROBOT_FILE_LIST)


class remove_button():
    def remove_functionality(self, ROBOT_FILE_LIST):
        sel = ROBOT_FILE_LIST.curselection()
        # iterate over sel, deleting each item
        for index in reversed(sel):
            ROBOT_FILE_LIST.delete(index)


if __name__ =="__main__":
    master = tkinter.Tk()
    master.title("Test Runner")
    master.geometry("750x500")
    master.resizable(width=False, height=False)
    Robot_Files_Found_Widgets()
    master.mainloop()

答案 1 :(得分:1)

方法.curselection()返回所选项目索引的元组。方法.delete()接受问题顶部错误中所述的数据,它将不接受元组。

您已将列表框的选择模式设置为MULTIPLE,因此您需要遍历curselection()返回的元组,并逐个删除每个索引。

def remove_functionality(self,ROBOT_FILE_LIST):
    sel = ROBOT_FILE_LIST.curselection()
    # iterate over sel, deleting each item
    for index in sel[::-1]:
        ROBOT_FILE_LIST.delete(index)