Python Tkinter Scrolled文本插入文本继承错误

Python Tkinter Scrolled文本插入文本继承错误,python,user-interface,inheritance,tkinter,Python,User Interface,Inheritance,Tkinter,我已经看过了大多数可用的Tkinter ScrolledText StackOverflow帖子,包括对发现的继承的描述:和。然而,在这个具体的例子中,我似乎无法理解为什么会出现以下错误: textBoxClass(self.parent).textDropIn(self.parent).insert(tk.INSERT,"This is the text to add.") AttributeError: 'NoneType' object has no attribute 'inse

我已经看过了大多数可用的Tkinter ScrolledText StackOverflow帖子,包括对发现的继承的描述:和。然而,在这个具体的例子中,我似乎无法理解为什么会出现以下错误:

    textBoxClass(self.parent).textDropIn(self.parent).insert(tk.INSERT,"This is the text to add.")
AttributeError: 'NoneType' object has no attribute 'insert'
我知道我没有
'insert'
的属性,但是我不明白为什么
textDropIn
函数没有
ScrolledText
的属性,基于我对
class textBoxClass(tkst.ScrolledText):
的类定义调用,但是我怀疑它是不正确的实例化(?)这就是为什么函数中不能继承
ScrolledText
属性的原因

我的另一部分怀疑我必须继承
someGui
类中
ScrolledText
的属性才能在类方法中调用它们,但我不确定

完整代码:

from tkinter import *
from tkinter import ttk
import tkinter as tk
import tkinter.scrolledtext as tkst


class someGui(tk.Tk):
    def __init__(self,parent):
        self.parent=parent
        self.Window()
        textBoxInstance=textBoxClass(self.parent)

    def Window(self): 
        self.parent.configure(bg='white')
        self.parent.geometry("1000x500")
        self.parent.title("Example Window")
        self.someFrame = ttk.Frame(self.parent)
        self.someFrame.grid(row=0, column=0, sticky=(N,S,E,W))

        textBoxSeparate=textBoxClass(self.parent)
        self.someFunction()

    def someFunction(self):
        #otherstuff
        textBoxClass(self.parent).textDropIn(self.parent).insert(tk.INSERT,"This is the text to add.")

class textBoxClass(tkst.ScrolledText):
    def __init__(self,parent):
        self.root=parent
        self.textDropIn(self.root)

    def textDropIn(self,parent):
        self.someText = tkst.ScrolledText(master=self.root, wrap=tk.WORD, width=50, height=20)
        self.someText.grid(row=0, column=4, rowspan=7, columnspan=4, pady=20, padx=20)


def main(): 
    root =tk.Tk()
    sg=someGui(root)
    root.mainloop()

if __name__=='__main__':
    main()
get()
属性调用的上下文中,此问题已被标记为与另一篇tkinter python文章重复,并带有
None
返回,但我进行了与建议给该用户的相同的行分隔编辑,但没有解决问题。如果有人能详细解释为什么它是重复的,我会很乐意删除这个问题。但是,我不明白为什么会这样

根据Bryan的第一个答案进行编辑 这是我的理解。我进行了编辑,但在编辑过程中遇到了几个错误。我删除了
tkst.ScrolledText
,因为我不正确地继承了属性并调用了它的实例。我删除了
textDropIn
函数中的
parent
属性以及
textBoxClass
定义中的
\uuuu init\uuuuu
。我还将
self.textBox=textBoxClass(self.parent)
添加到
someGui
类的
\uuuu init\uuuuu
中,但根据我的编辑,我遇到了
TypeError
递归error
。目前,它是一个递归错误,代码在当前版本中。这是由于self.textBox.textDropIn()没有传递任何参数

from tkinter import ttk
import tkinter as tk
import tkinter.scrolledtext as tkst


class someGui(tk.Tk):
    def __init__(self,parent):
        self.parent=parent
        self.Window()
        self.textBox=textBoxClass(self.parent) #saving the instance 

    def Window(self): 
        self.parent.configure(bg='white')
        self.parent.geometry("1000x500")
        self.parent.title("Example Window")
        self.someFrame = ttk.Frame(self.parent)
        self.someFrame.grid(row=0, column=0, sticky='nesw') #changed sticky definition for tk requirements

        textBoxSeparate=textBoxClass(self.parent) # the initial inclusion of the textbox in the frame
        self.someFunction() #no input needed

    def someFunction(self):
        #otherstuff
        self.textBox.textDropIn() #there is no parent attribute in textDropIn, so I removed it
        self.textBox.insert(tk.INSERT, "Some test text.") #split call to two lines and changed to tk.INSERT

class textBoxClass(): #removed tkst.ScrolledText in class call because instance was created in textDropIn
    def __init__(self,parent):
        self.root=parent
        super().__init__() #kept receiving TypeError: object.__init__() takes no arguments, thus removed args
        self.textDropIn() #removed parent attribute from function call

    def textDropIn(self): #removed parent attribute from definition
        self.someText = tkst.ScrolledText(master=self.root, wrap=tk.WORD, width=50, height=20)
        self.someText.grid(row=0, column=4, rowspan=7, columnspan=4, pady=20, padx=20)


def main(): 
    root =tk.Tk()
    sg=someGui(root)
    root.mainloop()

if __name__=='__main__':
    main()

错误告诉您,您正试图对
None
对象调用
insert
。那么,让我们看看您在哪里调用
insert

textBoxClass(self.parent).textDropIn(self.parent).insert(tk.INSERT,"This is the text to add.")
根据错误消息,我们必须得出结论,
textBoxClass(self.parent).textDropIn(self.parent)
None
。果然,当我们查看
textDropIn
方法的定义时,它没有显式返回任何内容。因为它没有显式返回任何内容,所以它将返回
None
。因此,代码与执行了
None.insert(…)
的代码相同,因此会出现错误

有两个显而易见的解决方案。如果希望能够像这样将方法链接在一起(例如:
.textDropIn(…).insert(…)
),则需要确保链中的每个步骤都返回原始对象。您可以这样做:

def someFunction(self):
    #otherstuff
    textBoxClass(self.parent).textDropIn(self.parent).insert(tk.INSERT,"This is the text to add.")
    return self
另一种方法是将一条长语句拆分为两条:

textBoxClass(self.parent).textDropIn(self.parent)
textboxClass(self.parent).insert(tk.INSERT,"This is the text to add.")
但是,这不是调用
textDropIn
insert
的正确方法。相反,您需要直接在类的实例上调用它。不幸的是,您没有保存对实例的引用,因此首先要通过保存实例来解决此问题:

class someGui(tk.Tk):
    def __init__(self,parent):
        self.parent=parent
        self.Window()
        self.textBox = textBoxClass(self.parent)
def someFunction(self):
    #otherstuff
    self.textBox.textDropIn(self.parent)
    self.textbox.insert(tk.INSERT,"This is the text to add.")
然后,您可以调用该实例上的方法:

class someGui(tk.Tk):
    def __init__(self,parent):
        self.parent=parent
        self.Window()
        self.textBox = textBoxClass(self.parent)
def someFunction(self):
    #otherstuff
    self.textBox.textDropIn(self.parent)
    self.textbox.insert(tk.INSERT,"This is the text to add.")
由于您从未使用
textDropIn
中的
parent
属性,因此建议从定义和调用中删除该参数

此外,如果所有类名都以大写字母开头,代码将更容易理解。您应该将
textBoxClass
更改为
textBoxClass
,将
someGui
更改为
someGui
。这种命名约定在python世界中是通用的。有关标准命名约定的详细信息,请参见

还有一个问题。
textBoxClass
既继承了
ScrolledText
,又创建了它的一个实例。你应该这样做或那样做。我不太清楚您想要完成什么,但是扩展现有类的正常方法是这样的(请注意
super
的用户):

代码中的另一个问题是导入tkinter两次:

from tkinter import *
...
import tkinter as tk
这使得代码很难理解。您需要选择一种导入方法并坚持使用它。我个人认为第二个版本是最好的,因为它遵循PEP8以及python的zen(显式优于隐式)

最后,还有一个问题。您正在创建两个根窗口,而tkinter程序只能有一个(除非在非常不寻常的情况下,情况并非如此)。一个是在执行
root=tk.tk()
时创建的,第二个是在执行
sg=someGui(root)
时创建的,因为
someGui
继承自
tk.tk
。要使问题复杂化,您没有正确调用超类
\uuuu init\uuuu
方法,因此
someGui
实例的构造不正确。这是您在更新中提到的递归错误的根源

from tkinter import ttk
import tkinter as tk
import tkinter.scrolledtext as tkst


class SomeGui(tk.Tk):
    def __init__(self):
        super().__init__()

    self.textBox=TextBoxClass(self) #saving the instance 
    self.configure(bg='white')
    self.geometry("1000x500")
    self.title("Example Window")
    self.someFrame = ttk.Frame(self)
    self.someFrame.grid(row=0, column=0, sticky='nesw') #changed sticky definition for tk requirements

    self.someFunction() #no input needed

    def someFunction(self):
        #otherstuff
        self.textBox.textDropIn() #there is no parent attribute in textDropIn, so I removed it
        self.textBox.someText.insert(tk.INSERT, "here we go")

class TextBoxClass(tkst.ScrolledText): #removed tkst.ScrolledText in class call because instance was created in textDropIn
    def __init__(self,parent):
        self.root=parent
        tkst.ScrolledText.__init__(self) #kept receiving TypeError: object.__init__() takes no arguments, thus removed args
        self.textDropIn()

    def textDropIn(self): #removed parent attribute from definition
        self.someText = tkst.ScrolledText(master=self.root, wrap=tk.WORD, width=50, height=20)
        self.someText.grid(row=0, column=4, rowspan=7, columnspan=4, pady=20, padx=20)


def main(): 
    sg=someGui()
    sg.mainloop()

if __name__=='__main__':
    main()

好的,我做了一些更改,并使用您的
someFunction
方法实现了所有更改。在评论中与Bryan交谈后,我意识到我们忘记初始化SomeGui类中的父类,这可能是导致递归错误的原因。也许有一种整理
TextBoxClass
的方法我也忽略了

通过一位朋友的贡献和我自己的实验,结合评论家们所说的内容,我在几周前找到了解决问题的方法

我知道这一点已经被否决了,因为这是一个错误的决定