Why is Label object not callable appearing - python

I am in the process of making an OOP Countdown GUI with the letters, numbers and conundrum games.
This is a snippet of my code so far.
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("Main")
self.configure(bg=LIGHT_BLUE)
self.title=tk.Label(master=self,bg=LIGHT_BLUE,font=("Arial",12,"bold"),text="!Countdown Games!",pady=5,padx=5)
self.title.pack()
self.frame=tk.Frame(master=self,bg=LIGHT_BLUE)
self.LettersButton=tk.Button(master=self.frame,bg=LIGHT_BLUE,font=("Arial",12,"bold"),text="Letters",command=self.start_letters)
self.LettersButton.grid(row=0,column=0,sticky="NESW",pady=10,padx=2)
self.NumbersButton=tk.Button(master=self.frame,bg=LIGHT_BLUE,font=("Arial",12,"bold"),text="Numbers",command=self.start_numbers)
self.NumbersButton.grid(row=0,column=1,sticky="NESW",pady=10,padx=2)
self.LettersButton=tk.Button(master=self.frame,bg=LIGHT_BLUE,font=("Arial",12,"bold"),text="Conundrum",command=self.start_conundrum)
self.LettersButton.grid(row=0,column=2,sticky="NESW",pady=10,padx=2)
self.frame.pack()
self.mainloop()
def start_letters(self):
self.withdraw()
self.Letters=Letters()
def start_numbers(self):
self.withdraw()
self.Numbers=Numbers()
def start_conundrum(self):
self.withdraw()
self.Conundrum=Conundrum()
class Conundrum(tk.Toplevel):
def __init__(self):
super().__init__()
self.configure(bg=LIGHT_BLUE)
self.geometry("400x150")
self.title("Conundrum")
self.frameA=tk.Frame(master=self,bg=LIGHT_BLUE)
self.letterList=[]
self.answer=r.choice(ninewords)
self.anagram=anagram(self.answer)
for x in range(9):
self.letterList.append(ConundrumDisplay(self.frameA,x))
self.frameA.pack()
self.frameB=tk.Frame(master=self,bg=LIGHT_BLUE)
self.letterEntryList=[]
for y in range(9):
self.letterEntryList.append(ConundrumEntry(self.frameB,y))
self.frameB.pack()
self.timer=tk.Label(master=self,bg=LIGHT_BLUE,font=("Arial",12,"bold"),text="31")
self.update_timer()
self.timer.pack()
self.mainloop()
m.showinfo("Startgame","The game will start when you press OK")
for x in range(9):
self.letterlist[x].add_letter(x,self.anagram)
self.bind("<Key>",self.process_key)
self.bind("Return",self.process_guess)
self.bind("BackSpace",self.process_back)
The upper bit of code is a method from an App class which inherits from tk.Tk
The error is in the super()._ _ init _ _() line in the conundrum class after you press the Conundrum button in the main wn
This conundrum class is obviously the bit of code just below which inherits from tk.Toplevel.
I have used tk.Toplevel before but it hasn't shown the error before.
I have tried to reduce the amount of code that I am posting but if any more of it is necessary to figure out the error, then I can amend the question.
Error Message:
Traceback (most recent call last):
File "/nix/store/2vm88xw7513h9pyjyafw32cps51b0ia1-python3-3.8.12/lib/python3.8/tkinter/__init__.py", line 1892, in __call__
return self.func(*args)
File "main.py", line 50, in start_conundrum
self.Conundrum=Conundrum()
File "main.py", line 55, in __init__
super().__init__()
File "/nix/store/2vm88xw7513h9pyjyafw32cps51b0ia1-python3-3.8.12/lib/python3.8/tkinter/__init__.py", line 2624, in __init__
self.title(root.title())
TypeError: 'Label' object is not callable

The error is telling you exactly what is wrong: you can't call a Label as if it was a function.
You are doing this: self.title(root.title()). root.title is an instance of Label but you are trying to call it as if it was a function. You get the same error if you do something like this:
foo = Label(...)
foo()
Since foo is a Label rather than a function, you can't call it.
If you want to call the title function of the root window, you should not name the label self.title. Name it something else so that you can use the title method of the base class.

Related

Python missing argument

Where is my fault
"this code is only part of my code
I just copied part of it"
import turtle
wn=turtle.Screen()
wn.bgcolor("black")
wn.title("Pacman")
wn.setup(900,700)
class Pacman(turtle.Turtle):
def __init__(self):
turtle.Turtle.__init__(self)
self.shape("square")
self.color("yellow")
self.penup()
self.speed(0)
def up(self):
self.goto(self.xcor(),self.ycor()+24)
def down(self):
self.goto(self.xcor(),self.ycor()-24)
def left(self):
self.goto(self.xcor()-24,self.ycor())
def right(self):
self.goto(self.xcor()+24,self.ycor())
wn.listen()
wn.onkey(Pacman.down, "Down")
wn.onkey(Pacman.up, "Up")
wn.onkey(Pacman.right, "Right")
wn.onkey(Pacman.left, "Left")
wn.tracer(0)
while True:
wn.update()
Fail
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\asus\AppData\Local\Programs\Python\Python37-
32\lib\tkinter\__init__.py", line 1702, in __call__
return self.func(*args)
File "C:\Users\asus\AppData\Local\Programs\Python\Python37-
32\lib\turtle.py", line 686, in eventfun
fun()
TypeError: up() missing 1 required positional argument: 'self'
When I click Right,Down,Up or Left Button square not moving and in console writing this fail
"Pacman" is a class template, so you can't call methods on it like that. You should either create a Pacman object (like so):
new_pacman = Pacman()
And then you could run your functions like so:
new_pacman.up()
Or (if I'm not mistaken) you could try this, which I think should also work:
Pacman().up() which
do pacman_instance = Pacman() right before wn.listen()
The issue is that you're trying to do an operation on a class rather than an instance of the class
If you just add Pacman = Pacman() before the line wn.listen(), it'll work!
The issue is you're trying to access a class that was not instantiated, and with this line you create this instance, and everything will work perfectly ;)

For loop inside a method : TypeError positional arguments

I'm trying to create a simple Gui with tkinter using classes.
But I don't really understand how to make the for-loop work inside the count method, could anyone tell me where should I add the missing argument?
from tkinter import *
import time
class App:
def __init__(self, master):
self.container1 = Frame(master)
self.container1.pack()
self.button1 = Button(self.container1, text="count")
self.button1.bind("<Button-1>", self.count)
self.button1.pack()
def count(self):
for i in range(100):
self.button1["text"] = str(i)
time.sleep(1)
root = Tk()
Myapp = App(root)
root.mainloop()
The error is:
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.5/tkinter/__init__.py", line 1553, in __call__
return self.func(*args)
TypeError: count() takes 1 positional argument but 2 were given
When you bind an event, a positional argument event is provided to the callback function.
Change your count method to this:
def count(self, event):
You will also need to get rid of time.sleep(1) since .sleep() is a blocking call, which means that it will block the tkinter mainloop which will cause your program to not respond.

root.after unable to find function_name

I am trying to put together a GUI that would read from a continuously updated TXT file and updated every once in a while. So far I succeeded with the first part and I am failing to use 'root.after()' to loop the whole thing but it results in NameError:
import tkinter as tk
root = tk.Tk()
class App:
def __init__(self, root):
frame = tk.Frame(root)
frame.pack()
iAutoInEN = 0
iAvailableEN = 0
self.tkAutoInEN = tk.StringVar()
self.tkAutoInEN.set(iAutoInEN)
self.tbAutoInEN = tk.Label(root, textvariable=self.tkAutoInEN)
self.tbAutoInEN.pack(side=tk.LEFT)
self.button = tk.Button(frame, text="Start", fg="red",
command=self.get_text)
self.button.pack(side=tk.LEFT)
def get_text(self):
fText = open("report.txt") #open a text file in the same folder
sContents = fText.read() #read the contents
fText.close()
# omitted working code that parses the text to lines and lines
# to items and marks them with numbers based on which they are
# allocated to a variable
if iLineCounter == 1 and iItemCounter == 3:
iAutoInEN = int(sItem)
self.tkAutoInEN.set(iAutoInEN)
root.after(1000,root,get_text(self))
app = App(root)
root.mainloop()
try:
root.destroy() # optional; see description below
except:
pass
The first instance runs without any problems and updates the value from 0 to the number in the TXT file but is accompanied with an error
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\...\Python35\lib\tkinter\__init__.py", line 1549, in __call__
return self.func(*args)
File "C:/.../pythonlab/GUI3.py", line 117, in get_text
self.after(1000,root,get_text())
NameError: name 'get_text' is not defined
EDIT:
When changed to the recommended "self.after(1000,self.get_text)"
class App:
...
def get_text(self):
fText = open("report.txt") #open a text file in the same folder
sContents = fText.read() #read the contents
fText.close()
# omitted code
if iLineCounter == 1 and iItemCounter == 3:
iAutoInEN = int(sItem)
self.tkAutoInEN.set(iAutoInEN)
self.after(1000,self.get_text)
Error changes
Traceback (most recent call last):
File "C:/.../pythonlab/GUI3.py", line 6, in <module>
class App:
File "C:/.../pythonlab/GUI3.py", line 117, in App
self.after(1000, self.get_text)
NameError: name 'self' is not defined
Also please consider this is my very first programme (not only) in Python, so I would appreciate if you are a little bit more explicit with your answers (e.g. when pointing out an indentation error, please refer to an exact line of code).
Because get_text is a method of App class you should call it as self.get_text.
After is a tkinter method. In that case you should call it as root.after. And self refers to the class you are in. So because get_text is a method of current class you should call is with self which is like this in other programming languages like Java.
...
root.after(1000, self.get_text)
...
Firstly, like James commented, you should fix your indentation so that the functions are a part of the class.
Then, change this line
root.after(1000,root,get_text(self))
to this
root.after(1000, self.get_text)
Check out the answer to the following question, which uses the code I just gave you:
Tkinter, executing functions over time

How to use pyglet within a class

In all the tutorials on the web I've seen with Pyglet, it doesnt seems that any of them have used classes to contain the pyglet.window.Window instance. For example, most tutorials seem to go something like
import pyglet
game_window = pyglet.window.Window()
#game_window.event
def on_draw():
#dostuff
while __name__ == "__main__":
pyglet.app.run()
I'm having trouble restructuring this code into a class. My code which is intended to do so, is here:
import pyglet
from pyglet.gl import *
from Board import Board
class Frontend:
def __init__(self,xs, ys):
self.GameInstance = Board(xs,ys)
self.GameWindow = pyglet.window.Window(width=512, height=512,visible=False)
#GameWindow.event
def on_draw(self):
self.GameWindow.clear()
f = Frontend()
When I run this code, I get the following error:
Traceback (most recent call last):
File "C:/Users/PycharmProjects/Nothing/2048/Frontend.py", line 7, in <module>
class Frontend:
File "C:/Users/PycharmProjects/Nothing/2048/Frontend.py", line 13, in Frontend
#GameWindow.event
NameError: name 'GameWindow' is not defined
When I replace #GameWindow.event with #self.GameWindow.event in an attempt to resolve the NameError I get:
Traceback (most recent call last):
File "C:/Users/PycharmProjects/Nothing/2048/Frontend.py", line 7, in <module>
class Frontend:
File "C:/Users/PycharmProjects/Nothing/2048/Frontend.py", line 13, in Frontend
#self.GameWindow.event
NameError: name 'self' is not defined
Which i expect. However, I'm not sure why this code isnt working - can someone explain why and how to fix it?
You can inherit from Window.
This should work:
class Frontend(pyglet.window.Window):
def __init__(self, xs, ys):
self.GameInstance = Board(xs,ys)
super().__init__(width=512, height=512,visible=False)
def on_draw(self):
self.clear()
Your code is not working because you can not reference the instance of the Frontend class outside the methods. If you will have only one instance of the Frontend class you can do something like:
class Frontend:
window = pyglet.window.Window()
def __init__(self):
...
#window.event
def on_draw():
...
As I've commented on ragezor's answer, the pyglet docs recommend inheritance.
But another option may be to separate the event handling logic in its own class, as an EventDispatcher:
http://pyglet.org/doc-current/programming_guide/events.html#creating-your-own-event-dispatcher
Personally, if I knew would only have one Frontend instance, I would question the necessity of having a class. But that's a whole can of worms. Thought I'd give you another nice option, at least, you can't go wrong inheriting from Window though, especially if all your events are Window-related.
A third idea (fourth I guess since ragezor gave you two options):
class Frontend:
def __init__(self,xs, ys):
self.GameInstance = Board(xs,ys)
self.GameWindow = pyglet.window.Window(width=512, height=512,visible=False)
self.on_draw = self.GameWindow.event(self.on_draw)
def on_draw(self):
self.GameWindow.clear()
In other words, apply the #GameWindow.event decorator manually.
One last thing, don't use camelcase for attributes, it goes against PEP8 convention and confused me for a second while editing this code. Call it game_window instead.
My guess is that you need to do
#self.Gamewindow.event

Python : AttributeError

I get an AttributeError I can't seem to work out.
I'm working with two classes.
The first class goes something like that.
class Partie:
def __init__(self):
# deleted lines
self.interface = Interface(jeu=self)
def evaluerProposition(self):
# computations
self.interface.afficherReponse()
Introducing second class (in a separate file).
class Interface:
def __init__(self, jeu):
self.jeu = jeu
self.root = tkinter.Tk()
# stuff
def onClick(self, event):
# talk
self.jeu.evaluerProposition()
def afficherReponse(self):
# stuff
I start the whole thing by
partie = Partie()
All manipulations on my widget work fine until some click event causes
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python33\lib\tkinter\__init__.py", line 1442, in __call__
return self.func(*args)
File "C:\Users\Canard\Documents\My Dropbox\Python\AtelierPython\Mastermind\classeInterface.py", line 197, in clic
self.jeu.evaluerProposition()
File "C:\Users\Canard\Documents\My Dropbox\Python\AtelierPython\Mastermind\classeJeu.py", line 55, in evaluerProposition
self.interface.afficherReponse()
AttributeError: 'Partie' object has no attribute 'interface'
I typed in the interpretor
>>> dir(partie)
and got a long list in return with 'interface' among the attributes.
Also typed
>>> partie.interface
<classeInterface.Interface object at 0x02C39E50>
so the attribute seems to exist.
Following the advice in some former post, I checked the instance names do not coincide with module names.
I am confused.
Most likely, in some code that you're not showing us, you're doing something like this:
self.some_button = tkinter.Button(..., command=self.interface.onClick())
Note the trailing () on onClick(). This would cause the onClick method to be called at the time the button is created, which is probably before your constructor is done constructing the instance of the Partie class.

Categories