-1

I get the following error in python 2.7, under the method updateText when I try to call self.editArea.insert().

AttributeError: 'App2' object has no attribute 'editArea'

My code is:

import Tkinter as tk
import threading

class App2(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)
        self.start()

    def callback(self):
        self.root.quit()

    def run(self):
        self.root = tk.Tk()
        self.root.protocol("WM_DELETE_WINDOW", self.callback)
        self.root.geometry("200x100")
        self.COMframe = tk.Frame(self.root, width=200, height=100, bg = '#ffffff', borderwidth=1, relief="sunken")
        self.scrollbar = tk.Scrollbar(self.COMframe)
        self.editArea = tk.Text(self.COMframe, width=200, height=100, yscrollcommand=self.scrollbar.set, borderwidth=0, highlightthickness=0)
        self.scrollbar.config(command=self.editArea.yview)
        self.scrollbar.pack(side="right", fill="y")
        self.editArea.pack(side="left", fill="both", expand=True)
        self.COMframe.grid(row=1, column=1)

        #self.editArea.config(state=tk.NORMAL)
        #self.editArea.delete(1.0, tk.END)
        self.editArea.insert(tk.END, "hello world\n this is my text")
        #self.editArea.config(state=tk.DISABLED)

        self.root.mainloop()

    def updateText(self, string):
        #self.editArea.config(state=tk.NORMAL)
        #self.editArea.delete(1.0, tk.END)
        self.editArea.insert(tk.END, string)
        #self.editArea.config(state=tk.DISABLED)

app2 = App2()

r = 0
while True:
    s = "r={}".format(r)
    app2.updateText(s)

    r = r+1
    print s

I don't understand why python won't see editArea. Does it have to do with the fact that it is declared in run(self)?

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
knap720
  • 1
  • 2
  • The assignment to `self.editArea` is like any other assignment; it will happen when `run` is *called*, not defined. If it needs to be used in other methods, you need to either move it to `__init__` or guaranteed that `run` will be called before `updateText`. – chepner Sep 23 '15 at 02:13
  • i assume that the 'run' method was called because the tkinter GUI pops up when I take out the 'updateText' method. – knap720 Sep 23 '15 at 02:15
  • You have a race condition in your code. The `run` method may not have reached the line creating `self.editArea` by the time you call `updateText` in the main thread. I'd suggest moving the creation of the TK components into the `__init__` function. – Paul Rooney Sep 23 '15 at 02:23
  • Also be aware you should not run the mainloop anywhere except the main thread see [here](http://stackoverflow.com/questions/14694408/runtimeerror-main-thread-is-not-in-main-loop) – Paul Rooney Sep 23 '15 at 02:28

1 Answers1

0

You define self.editText in the run method, but you never call the run method (or you call it by some code you didn't show us).

Bottom line: you must define an instance variable before you try to use it, but your code is running in an order where updateText is being called before run, which can be proven with a couple of print statements.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685