0
votes

I am trying to create a Tkinter widget class using an existing Tkinter widget class. My existing Tkinter widget class is a scrolled text widget class and the widget class I am trying to create uses my existing scrolled text widget class to create a widget that combines two of the existing scrolled text widgets to create a single composite widget. I have written code that seems close to being correct but is giving me an error message. Here is my existing functional scrolled text widget class code:

class ScrolledText(Frame):
def __init__(self, parent=None, text='', file=None, width='', height=''):
    Frame.__init__(self, parent)
    self.pack(expand=YES, fill=BOTH)                # make me expandable
    self.width = width
    self.height = height
    self.makewidgets()
    self.settext(text, file)
def makewidgets(self):
    sbar = Scrollbar(self)
    text = Text(self, relief=SUNKEN, width=self.width, height=self.height)
    sbar.config(command=text.yview)                  # xlink sbar and text
    text.config(yscrollcommand=sbar.set)             # move one moves other
    sbar.pack(side=RIGHT, fill=Y)                    # pack first=clip last
    text.pack(side=LEFT, expand=YES, fill=BOTH)      # text clipped first
    self.text = text
def settext(self, text='', file=None):
    if file: 
        text = open(file, 'r').read()
    self.text.delete('1.0', END)                     # delete current text
    self.text.insert('1.0', text)                    # add at line 1, col 0
    self.text.mark_set(INSERT, '1.0')                # set insert cursor
    self.text.focus()                                # save user a click
def gettext(self):                                   # returns a string
    return self.text.get('1.0', END+'-1c')           # first through last

Here is the code I have written that makes a new scrolled text widget that is a composite of two of the existing scrolled text widgets:

class ScrolledTextComposite(Frame):
def __init__(self, parent=NONE):
    Frame.__init__(self, parent)
    self.pack(expand=YES, fill=BOTH)
    self.makeWidgets()
    self.text1 = 'aaaaaa'
    self.text2 = 'bbbbbbb'

def makeWidgets(self):

    try:
        self.top = ScrolledText(self, file=sys.argv[1], width= 50, height=15).pack()
    except IndexError:
        self.top = ScrolledText(self, text= self.text1, width= 50, height=15).pack()

    try:
        self.bot = ScrolledText(self,file=sys.argv[1], width=50, height=15).pack()
    except IndexError:
        self.bot = ScrolledText(self, text= self.text2, width=50, height=15).pack()

My functioning ScrolledText widget class creates a text widget that scrolls and allows for the text in the text widget to be input either as a file or as a text string. In this case I am using a text string and not a file for the source of the text to be displayed. The try except statements in the makeWidget portion of the ScrolledTextComposite class are a result of the ScrolledText class's ability to handle either a file or a text string as input. Here is the mainloop expression that draws the new composite scrolled text widget:

ScrolledTextComposite().mainloop()

When I run this code I get the following error message:

AttributeError: 'str' object has no attribute 'tk'

I believe this error is being caused by how I am coding the ScrolledTextComposite class to input the text string to be displayed in the individual text widgets that the ScrolledTextComposite widget is comprised of. If anybody has any ideas how to make the ScrolledTextComposite class function properly I would appreciate the help. Sincerely, George

1
I don't think this is the cause of your problem, but doing var = Widget(whatever).pack() will cause the var variable to have a value of None, because pack doesn't return anything. Assignment and packing should be done on separate lines. - Kevin
The indentation is incorrect in your code. - Bryan Oakley

1 Answers

4
votes
class ScrolledTextComposite(Frame):
    def __init__(self, parent=NONE):

NONE is a string constant created by Tkinter. You want the built-in object None. Also, remember to initialize your text1 and text2 values before you call makeWidgets.

class ScrolledTextComposite(Frame):
    def __init__(self, parent=None):
        Frame.__init__(self, parent)
        self.pack(expand=YES, fill=BOTH)
        self.text1 = 'aaaaaa'
        self.text2 = 'bbbbbbb'
        self.makeWidgets()