Azhraam
Azhraam

Reputation: 77

Tkinter: Grab content of a ScrolledText text pad

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.

Upvotes: 1

Views: 2233

Answers (1)

Joseph Farah
Joseph Farah

Reputation: 2534

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!!

Upvotes: 2

Related Questions