-1

I am following the tutorial (more or less) at this site. I am able to copy and paste the code from the tutorial and modify it with the Python 3 module names (Tkinter becomes tkinter, Queue becomes queue, etc.) and the code runs fine.

However, my code creates widgets in a method.

import tk inter as tk
class ClientUI:
    def __init__(self, master, queue, send_command):
        self.queue = queue
        self.send_command = send_command
        self.master = master
        menu_bar = tk.Menu(master)
        menu_file = tk.Menu(menu_bar, tearoff=0)
        menu_file.add_command(label="Preferences", command=self.show_preferences)
        menu_file.add_command(label="Quit", command=master.destroy)
        menu_bar.add_cascade(label="Client", menu=menu_file)
        master.config(menu=menu_bar)
        master.grid()
        self.create_widgets()
        ...

    def create_widgets(self):
        output = tk.Text(self.master, state=tk.DISABLED, name="output")
        output.grid(row=0)

        input_area = tk.Entry(self, name="input")
        input_area.bind("<Return>", self.send_command)
        input_area.focus()
        input_area.grid(row=1, sticky=tk.W+tk.E)

    ...

class Client:
    def __init__(self, master):
        # super(Client, self).__init__()
        self.master = master
        self.queue = Queue()
        self.ui = ClientUI(master, self.queue, self.send)
        ...

    ...

root = tk.Tk()
client = Client(root)
root.mainloop()

When I try to run this I get the error

    output = tk.Text(self.master, state=self.master.DISABLED, name="output")
AttributeError: 'ClientUI' object has no attribute 'tk'

I don't understand why he sets root = tk.Tk() and how I can access the tkinter module to create widgets.

Marshall Davis
  • 3,337
  • 5
  • 39
  • 47
  • 3
    I don't see `output = self.master.tk.Text(...)` in your code. Please read http://stackoverflow.com/help/mcve – jonrsharpe Apr 11 '15 at 08:34
  • There's also no `tkapp` as mentioned in the `AttributeError` message. It's also unclear what the relationship is of your code to the [linked asynchronous I/O code](http://code.activestate.com/recipes/82965-threads-tkinter-and-asynchronous-io/) recipe. – martineau Apr 11 '15 at 09:54
  • Where's the `import tkinter as tk` statement in all this? If one has been executed, then the global variable named `tk` should be accessible to all the code in the same module. – martineau Apr 11 '15 at 09:59
  • I thought that global should, my issue is it is not. – Marshall Davis Apr 11 '15 at 13:32
  • @martineau I corrected the mistake. I was working on it when asking and copied a previous error. I tried replacing `tk.` with `self.master` as a long shot. For whatever reason `self.master` seems to be a `tkapp` – Marshall Davis Apr 11 '15 at 13:58
  • Your code can't possibly give the error you say it does -- the very first line will give you an import error. Please be precise about what error your're getting, and show the actual code that gives that error. – Bryan Oakley Apr 11 '15 at 14:58
  • You need a `import tkinter as tk` not `import tk inter as tk` which would produce a `SyntaxError: invalid syntax`. – martineau Apr 11 '15 at 17:09
  • It's a little frustrating that it can't be assumed everything else works if I am only asking about one error. I completely understand why, though. Anyway, that's what I get for trying to respond on my mobile. The line should be `import tkinter as tk`, it's not an issue with importing `tkinter`. – Marshall Davis Apr 12 '15 at 02:33

2 Answers2

0

Your error message (but oddly, not your code) shows the error is on this line:

output = self.master.tk.Text(...)

Assuming that you imported tkinter as tk, you want to do this:

output = tk.Text(...)
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • I changed it trying to figure it out. `tk.Text ()` seems correct but the global `tk` isn't available. – Marshall Davis Apr 11 '15 at 13:54
  • @ToothlessRebel: the code in your question clearly shows you're using `tk.Tk()`, so if it works there it simply must work elsewhere, unless you're creating a variable named `tk` somewhere. – Bryan Oakley Apr 11 '15 at 14:57
  • That's exactly what I thought. I didn't think I may be creating a variable named `tk` somewhere. I will look for that. – Marshall Davis Apr 12 '15 at 02:33
0

The problem lies in the following function, or similar usages. @bryan helped me to determine it by looking for incorrectly assigned variables.

def create_widgets(self):
    output = tk.Text(self.master, state=tk.DISABLED, name="output")
    output.grid(row=0)

    // This line:
    input_area = tk.Entry(self, name="input")
    input_area.bind("<Return>", self.send_command)
    input_area.focus()
    input_area.grid(row=1, sticky=tk.W+tk.E)

The line input_area = tk.Entry(self, name="input) is passing in self which is of the ClientUI class, and does not have a tk method. Why the global tk was not used I cannot be sure. However, passing self.master which is of the Tk class as the first argument and does have such attribute. This resolved the error message.

Marshall Davis
  • 3,337
  • 5
  • 39
  • 47