【问题标题】:Change an attribute from an instance with a tkinter Listbox使用 tkinter 列表框从实例更改属性
【发布时间】:2020-04-15 14:14:42
【问题描述】:

我是新来的,我是 tkinter 的初学者。我想从类中更改特定实例的属性。要选择实例,我想使用一个列表框。这是创建列表框的代码的简单版本。是否可以更改所选实例的标志属性(如果点击了apple,请将apple.flag更改为1)?

谢谢!

import tkinter as tk

class fruits:
    all_fruits = []
    def __init__(self,name):
        self.flag = 0
        self.name = name
        fruits.all_fruits.append(self.name)

root = tk.Tk()
#Main window
frame = tk.Frame(root)
frame.pack()
#Fruits selection
selectorlist = tk.Listbox(frame)
selectorlist.pack()

#Fruits creation
apple = fruits('apple')
pear = fruits('pear')

#List creation
for item in fruits.all_fruits:
        selectorlist.insert(tk.END, item)

#Effect on click
selectorlist.bind("<Button-1>",lambda *a: print("Flag is 1"))
root.mainloop()

【问题讨论】:

    标签: python-3.x class tkinter listbox bind


    【解决方案1】:

    通过一些更改可以完成,我尝试添加尽可能多的 cmets 来帮助解释原因。

    import tkinter as tk
    
    class fruits:
        def __init__(self, name):
            self.flag = 0
            self.name = name
    
    def clicked(e):
        # Function that gets the selected value, then changes the flag property and prints the flag.
        selected = e.widget.get(e.widget.curselection()) # Gets the index of the current selection and retrieves it's value.
        all_fruits[selected].flag = 1
        print(selected, "changed to", all_fruits[selected].flag)
    
        test() # This is a function call to print the entire dictionary so changes can be seen.
    
    def test():
        # Function to print the all_fruits dictionary.
        for k,v in all_fruits.items():
            print(k, v.flag)
        print()
    
    root = tk.Tk()
    #Main window
    frame = tk.Frame(root)
    frame.pack()
    #Fruits selection
    selectorlist = tk.Listbox(frame)
    selectorlist.pack()
    
    #Fruits creation
    names = ['apple', 'pear', 'grape', 'orange', 'pineapple'] # List of fruit names.
    
    all_fruits = {} # Define a dictionary for all fruits.
    for name in names:
        # Add each name as a dictionary key with the class as its value.
        all_fruits[name] = fruits(name)
    
    #List creation
    for item in all_fruits:
        # Insert each dictionary key into the listbox
        selectorlist.insert(tk.END, item)
    
    #Effect on click
    selectorlist.bind("<<ListboxSelect>>", clicked) # Changed this to call a function
    
    root.mainloop()
    

    要实现添加/删除功能,最好重组类,以便有一个单独的类来管理所有水果。

    我添加了一些用于添加/删除的功能,以后可能会有所帮助:

    import tkinter as tk
    
    class fruit:
        """A Class for each fruit."""
        def __init__(self, name):
            self.flag = 0
            self.name = name
    
        def change(self, value):
            self.flag = value
    
    class fruits:
        """A Class for all the fruits."""
        def __init__(self):
            self.all_fruits = {}
    
        def add(self, listbox, name):
            self.all_fruits[name] = fruit(name)
            listbox.insert(tk.END, name)
            print("Added", name)
    
        def remove(self, listbox, name):
            indx = listbox.get(0, tk.END).index(name)
            listbox.delete(indx)
            del self.all_fruits[name]
            print("Deleted", name)
    
        def change(self, name, value):
            self.all_fruits[name].change(value)
    
    def clicked(e):
        # Function that gets the selected value, then changes the flag property and prints the flag.
        selected = e.widget.get(e.widget.curselection()) # Gets the index of the current selection and retrieves it's value.
        Fruits.change(selected, 1)
        print(selected, "changed to 1")
    
        test() # This is a function call to print the entire dictionary so changes can be seen.
    
    def test():
        # Function to print the all_fruits dictionary.
        for k,v in Fruits.all_fruits.items():
            print(k, v.flag)
        print()
    
    root = tk.Tk()
    #Main window
    frame = tk.Frame(root)
    frame.pack()
    #Fruits selection
    selectorlist = tk.Listbox(frame)
    selectorlist.pack()
    
    #Fruits creation
    names = ['apple', 'pear', 'grape', 'orange', 'pineapple', 'carrot'] # List of fruit names.
    
    Fruits = fruits() # Creates an instance of fruits
    
    for name in names:
        Fruits.add(selectorlist, name) # Add each name with the class's add function.
    
    Fruits.remove(selectorlist, "carrot")
    
    #Effect on click
    selectorlist.bind("<<ListboxSelect>>", clicked) # Changed this to call a function
    
    root.mainloop()
    

    【讨论】:

    • 感谢您的帮助。它有效,但为什么我不能使用类中的 all_fruits 列表作为名称? (如果我将 all_fruits 列表放在类中,它适用于创建列表,但在 click 函数中不起作用。selected 返回名称而不是索引)。是否可以在类中创建“字典键”? (后面我要加删水果)
    • @Dr.TK 我添加了我会使用的方法,基本上是添加一个类来处理所有的水果。
    • 非常感谢@tgikal 的回答和解释。现在我知道如何管理我所有的水果了。创建一个单独的类似乎是一个不错的解决方案。
    • @Dr.TK 我确实在删除函数中有错字,我在添加循环下方添加了一个测试,它添加,然后删除“胡萝卜”。
    猜你喜欢
    • 1970-01-01
    • 2018-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-02
    • 2018-01-20
    • 2023-01-08
    • 2010-11-10
    相关资源
    最近更新 更多