首页 > 解决方案 > 在 tkinter 中定位自定义小部件

问题描述

我试图在一个窗口中放置一个自定义小部件的多个实例,目标是用户将项目从Listbox一个小部件移动到另一个小部件。

我的小部件类:

import tkinter as tk

class DistriBox(tk.Frame):
    def __init__(self, parent, name):
        tk.Frame.__init__(self, parent)
        self.parent = parent
        self.label = tk.Label(self, text=name, anchor="center")
        self.label.grid(column=0, row=0)
        self.lb_locs = tk.Listbox(self, width=15, height=5)
        self.lb_locs.grid(column=0, row=1)

    def __iter__(self):
        return self

    def __getitem__(self, key):
        return self.lb_locs.size()

    def __setitem__(self, key, value):
        print('entering __setitem__ with %4d and %s' % (key, value))
        items_already = self.lb_locs.size()
        self.lb_locs.insert(items_already, value)

和应用程序:

import tkinter as tk
import DistriBox as db

class App(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.parent = parent

        group1 = []
        for i in range(0,3):
            group1.append(db.DistriBox(self, 'group 1'))
            group1[i].grid(column=0, row=i)

        group1[0] = 'California'
        group1[1] = 'Utah'

if __name__ == "__main__":
    root = tk.Tk()
    root.geometry('650x600')
    App(root).grid(column=0, row=0)
    root.mainloop()

问题:

标签: pythonclasstkinterindexing

解决方案


正如@Bryan Oakley 在评论中提到的那样,range()如果你想要四个小部件,你就没有正确使用(当它为零时也没有必要指定起始值)。诚然,文档很模糊,所以我理解你的困惑。

至于为什么没有插入项目,这是因为您没有DistriBox正确引用小部件的实例 -group1是它们的列表,所以要引用其中一个并调用它的__setitem__()方法,您需要有两个级别的索引,如图所示以下。请注意,我还更改了name每个自定义小部件的 ,以便更容易区分它们。

import tkinter as tk
import DistriBox as db

class App(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.parent = parent

        group1 = []
        for i in range(4):  # CHANGED.
            group1.append(db.DistriBox(self, f'group {i}'))  # CHANGED.
            group1[i].grid(column=0, row=i)

        group1[0][0] = 'California'  # FIXED INDEXING.
        group1[0][1] = 'Utah'        # FIXED INDEXING.

if __name__ == "__main__":
    root = tk.Tk()
    root.geometry('650x600')
    App(root).grid(column=0, row=0)
    root.mainloop()

推荐阅读