TKinter子对象:TypeError:列表索引必须是整数或片,而不是str

2024-06-30 15:02:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我对python有一定的经验,而且对tkinter还很陌生。我试图在2x2的网格中安排四个帧,但我知道我失败得很惨。我试图创建一个MWE,但即使失败了,因为它既不能工作,也不能重现我的实际问题,而是产生了一个自己的问题。但首先,MWE代码如下:

import tkinter as tk
from tkinter import ttk


class DummyParent(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        master.title('Test')
        self.children = []
        for i in range(4):
            self.children.append(DummyChild(self))
            self.children[i].grid(row=i//2, column=i%2)


class DummyChild(ttk.Frame):
    def __init__(self, master):
        super().__init__(master)
        self.state(ttk.Label(text='Test'))


root = tk.Tk()

dP = DummyParent(master=root)
dP.mainloop()

这将导致以下堆栈跟踪:

  File "E:/TI/internetofthings/python/tkinter_test.py", line 23, in <module>
    dP = DummyParent(master=root)
  File "E:/TI/internetofthings/python/tkinter_test.py", line 11, in __init__
    self.children.append(DummyChild(self))
  File "E:/TI/internetofthings/python/tkinter_test.py", line 17, in __init__
    super().__init__(master)
  File "C:\Users\Scipio\anaconda3\lib\tkinter\ttk.py", line 742, in __init__
    Widget.__init__(self, master, "ttk::frame", kw)
  File "C:\Users\Scipio\anaconda3\lib\tkinter\ttk.py", line 559, in __init__
    tkinter.Widget.__init__(self, master, widgetname, kw=kw)
  File "C:\Users\Scipio\anaconda3\lib\tkinter\__init__.py", line 2292, in __init__
    BaseWidget._setup(self, master, cnf)
  File "C:\Users\Scipio\anaconda3\lib\tkinter\__init__.py", line 2285, in _setup
    self.master.children[self._name] = self
TypeError: list indices must be integers or slices, not str

发生错误时self._name的值为!dummyparent。真正让我困惑的是,我的原始代码在这一点上运行得非常好,甚至更糟,即使添加了一些实际的功能,它也几乎是一样的。在库代码的同一行self._name的值是!firefightermonitor,这是等效的类名(小写,带前导感叹号,与MWE一样)。你知道我在这里遗漏了什么吗?还是我只是用错了tkinter


Tags: inpyselfmasterinittkinterlibline
1条回答
网友
1楼 · 发布于 2024-06-30 15:02:10

代码中有很多小问题

不幸的是,最大的问题是您正在定义self.children,它与同名的内部(遗憾的是,没有文档记录)属性冲突。您需要将属性重命名为其他属性。我不知道你为什么把孩子们排成一排。Tkinter为您做了这件事,所以我认为self.children列表根本没有必要

下一个问题是,您不应该以现在的方式调用self.state。这根本不是你使用self.state的方式

DummyChild中的标签必须是self的子标签。您忽略了传递父级/主级,因此它默认为root的子级

您需要在标签上调用packplacegrid,以便它出现在子标签中。您还需要在dP上调用其中一个方法,以便它出现在根目录中

这将创建一个2x2网格,标签可见:

import tkinter as tk
from tkinter import ttk


class DummyParent(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        master.title('Test')
        for row in range(0,2):
            for column in range(0,2):
                child = DummyChild(self)
                child.grid(row=row, column=column, sticky="nsew")


class DummyChild(ttk.Frame):
    def __init__(self, master):
        super().__init__(master)
        self.label = ttk.Label(self, text='Test')
        self.label.pack()

root = tk.Tk()

dP = DummyParent(master=root)
dP.pack()
dP.mainloop()

相关问题 更多 >