0

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

2
  • 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. Commented Dec 8, 2014 at 13:02
  • 1
    The indentation is incorrect in your code. Commented Dec 8, 2014 at 15:19

1 Answer 1

4
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()
Sign up to request clarification or add additional context in comments.

5 Comments

Hi, Thank you very much for your response. I reordered my text1 and text2 values which in hindsight seems obvious. However I don't fully understand what you mean when you say I want the built-in object None. Would you please elaborate. Thanks, George
Ok. None is a constant value provided by Python that is frequently used to represent the absence of a value, as when default arguments are not passed to a function. You yourself used it higher up in your program, in the __init__ method for ScrolledFrame. Tkinter accepts None as the parent parameter to its Widget classes, in contrast to NONE, which it rejects.
OK, I sort of understand that but I don't understand how that affects my ScrolledTextComposite code. It seems like you are saying that by defining parent=None in the init portion of the ScrolledTextComposite code I am disallowing the use of any variables within that code? Thanks for your help but I am still confused. Sincerely, George
All I'm saying is, parent=NONE is wrong, parent=None is correct.
Ahh, Thank you very much. I was overanalyzing your answer and didn't realize what you were referring to. Thank you very much for your answer, my code works as desired now. Sincerely, George

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.