Tkinter: Grab content of a ScrolledText text pad

Question:

all. I’m working on a simple Notepad-like program that saves files and closes the program when the escape key is pressed. I mention this because it is in this method that the program runs into problems. textpad is a ScrolledText object.

This line:

`contents = self.textPad.get(self, 1.0, END)`

results in the following error:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1535, in __call__
    return self.func(*args)
  File "todopad.py", line 24, in save_and_quit
    contents = self.textPad.get(self, 1.0, END)
AttributeError: Event instance has no attribute 'textPad'

I know this is the problem, because the program executes and terminates without issue when this line is commented out. Although I don’t understand the error at all.

This has been a very long-winded way of asking: How can I retrieve the contents of a ScrolledText text pad and save it to a variable or directly write it to a file? And also an explanation about the error message?

Thank you in advance.

EDIT: As requested, here is the code for the entire thing.

import sys
import Tkinter
from Tkinter import *
from ScrolledText import *

root = Tkinter.Tk(className = "TodoPad");
textPad = ScrolledText(root, width = 80, height = 20)

def start_and_open():
    textFile = open('/home/colin/documents/prog/py/todopad/todo', 'r')
    contents = textFile.read()
    textPad.insert('1.0', contents)
    textFile.close()

def save_and_quit(self):
    textFile = open('/home/colin/documents/prog/py/todopad/todo', 'w')
    #contents = self.textPad.get(self, 1.0, END) # The line in question
    #textFile.write(contents)
    textFile.close()
    root.destroy()

textPad.pack()
root.bind('<Escape>', save_and_quit)
root.after(1, start_and_open)
root.mainloop()

Since I have posted the whole thing I may as well explain the rationale behind everything. It’s supposed to be a fast little thing that opens a to-do list and displays what’s already on the list in the text box. I make whatever edits I like, then it saves before closing when I hit escape, problem being is that it doesn’t like closing because of the line that I mentioned previously in my post.

Asked By: Azhraam

||

Answers:

First of all, kudos on identifying the problem.

Placing the Widget

To answer what is going wrong: you need to actually place the widget into the window frame. You have a choice between .grid() and .pack(). The first allows you to pick exactly where you want it to go, the second puts in a (technically) default location.

Right now, the instance of your widget is not preset, so your program has no idea where to pull the value from. You have to set a location. i would recommend using .grid(), but for the example .pack() will work as well.

textPad = ScrolledText(root, width = 80, height = 20)
textPad.pack()

Try this, and see if it works. This should fix it, but I could be wrong.

Do NOT just do

textPad = ScrolledText(root, width = 80, height = 20).pack()

The pack() function returns a NULL and will nullify your widget.

Your Issue With Self

Finally, why are you using self at all? You are not using any classes–you need to globalize the variable. The error that is thrown is a result of your program not knowing what class you are pulling the self instance from. Remove the self variables from the program, and put this into the function:

global textPad

This will make it global and all functions will be able to use it.

This should solve all the problems you have right now. However, give it a try and report what happens.

Here are some resources on global variables, getting input from widgets, and saving to files;

http://www.python-course.eu/python3_global_vs_local_variables.php

http://effbot.org/tkinterbook/text.htm

http://www.afterhoursprogramming.com/tutorial/Python/Writing-to-Files/

Happy coding, and best of luck!!

Answered By: Joseph Farah
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.