I am fairly new to python and with the help of tutorials I am trying to create a calculator but got stuck due to an error which I am unable to correct which occurs when I press a number button
from tkinter import *
root=Tk()
root.title("Yuvi's CAl")
global char
class cal():
def __init__(self):
self.string= StringVar()
root=Tk()
root.title("Yuvi's CAl")
self.string=StringVar
enter=Entry(root,textvariable=self.string)
enter.grid(row=0,column=0,columnspan=6)
values=["1","2","3","4","5","+","6","7","=","8","9","c"]
row=1
col=0
i=0
for txt in values:
if i==3:
row=3
col=0
if i==6:
row=4
col=0
if i==9:
row=5
col=0
if txt=="+":
but=Button(root,text=txt)
but.grid(row=row,column=col)
elif txt=="=":
but=Button(root,text=txt,command=lambda:self.equals)
but.grid(row=row,column=col)
elif txt=="c":
but=Button(root,text=txt,command=lambda:self.clr)
but.grid(row=row,column=col)
else:
but=Button(root,text=txt,command=lambda txt=txt:self.add(txt))
but.grid(row=row,column=col)
col+=1
i+=1
def add(self,char):
meet=self.string.get(self)
self.string.set((str(meet)) + (str(char)))
def equals(self):
result=eval(self.string.get())
self.string.set(result)
def clr(self):
self.string.set("")
ent=cal()
root.mainloop()
and this being the error when I press a number button
Traceback (most recent call last):
File "/usr/lib/python3.4/tkinter/__init__.py", line 1541, in __call__
return self.func(*args)
File "/home/yuvi/Documents/LiClipse Workspace/GUI/src/Misiio_calcuator.py", line 40, in <lambda>
but=Button(root,text=txt,command=lambda txt=txt:self.add(txt))
File "/home/yuvi/Documents/LiClipse Workspace/GUI/src/Misiio_calcuator.py", line 46, in add
meet=self.string.get(self)
File "/usr/lib/python3.4/tkinter/__init__.py", line 339, in get
value = self._tk.globalgetvar(self._name)
AttributeError: 'cal' object has no attribute '_tk'
Do rectify if any mistakes
Thank you in advance
There are several issues with your code first you should remove hiding your global vars within your __init__ as it creates two windows and only running mainloop for one of them. In addition you overwrite self.string with the StringVar class object after first creating an instance of it. So your __init__ could look like so
...
def __init__(self):
self.string=StringVar()
enter=Entry(root,textvariable=self.string)
enter.grid(row=0,column=0,columnspan=6)
values=["1","2","3","4","5","+","6","7","=","8","9","c"]
row=1
col=0
i=0
...
then in your add you don't have to pass self to self.string.get, that is it should look like
...
def add(self,char):
meet=self.string.get()
self.string.set((str(meet)) + (str(char)))
...
Those changes fixes your exception but I guess there are still other logical mistakes in the calculator, however that's not what the question is about and fixing them wouldn't help you learning python.
Related
My code:
from tkinter import *
from tkinter.ttk import Combobox
import random
screen = Tk()
screen.title("Password Generator")
screen.geometry('600x400')
screen.configure(background ="gray")
def Password_Gen():
global sc1
sc1.set("")
passw=""
length=int(c1.get())
lowercase='abcdefghijklmnopqrstuvwxyz'
uppercase='ABCDEFGHIJKLMNOPQRSTUVWXYZ'+lowercase
mixs='0123456789'+lowercase+uppercase+'##$%&*'
if c2.get()=='Low Strength':
for i in range(0,length):
passw=passw+random.choice(lowercase)
sc1.set(passw)
elif c2.get()=='Medium Strength':
for i in range(0,length):
passw=passw+random.choice(uppercase)
sc1.set(passw)
elif c2.get()=='High Strength':
for i in range(0,length):
passw=passw+random.choice(mixs)
sc1.set(passw)
sc1=StringVar('')
t1=Label(screen,text='Password Generator',font=('Arial',25),fg='green',background ="gray")
t1.place(x=60,y=0)
t2=Label(screen,text='Password:',font=('Arial',14),background ="gray")
t2.place(x=145,y=90)
il=Entry(screen,font=('Arial',14),textvariable=sc1)
il.place(x=270,y=90)
t3=Label(screen,text='Length: ',font=('Arial',14),background ="gray")
t3.place(x=145,y=120)
t4=Label(screen,text='Strength:',font=('Arial',14),background ="gray")
t4.place(x=145,y=155)
c1=Entry(screen,font=('Arial',14),width=10)
c1.place(x=230,y=120)
c2=Combobox(screen,font=('Arial',14),width=15)
c2['values']=('Low Strength','Medium Strength','High Strength')
c2.current(1)
c2.place(x=237,y=155)
b=Button(screen,text='Generate!',font=('Arial',14),fg='green',background ="gray",command=gen)
b.place(x=230,y=195)
screen.mainloop()
For some reason I'm keep getting those errors:
Traceback (most recent call last):
File "C:\Users\z\3D Objects\birthday\passwordgeneratorgui.py", line 32, in <module>
sc1=StringVar('')
File "C:\Users\z\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 540, in __init__
Variable.__init__(self, master, value, name)
File "C:\Users\z\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 372, in __init__
self._root = master._root()
AttributeError: 'str' object has no attribute '_root'
How can I fix those errors?
This is because the first argument to StringVar should be the "container". You are passing in an empty string instead of that. Replace the line sc1=StringVar('') with sc1=StringVar(). You can also read a guide to StringVars like this one: https://www.pythontutorial.net/tkinter/tkinter-stringvar/
Another mistake in your code is in this line:
b=Button(screen,text='Generate!',font=('Arial',14),fg='green',background ="gray",command=gen)
The problem is that you are passing in a function gen, which doesn't exist. I guess that you want to call the function Password_Gen with this button. So, replace it with this line:
b=Button(screen,text='Generate!',font=('Arial',14),fg='green',background ="gray",command=Password_Gen)
EDIT:
I have also noticed a minor problem with your password generator.
lowercase='abcdefghijklmnopqrstuvwxyz'
uppercase='ABCDEFGHIJKLMNOPQRSTUVWXYZ'+lowercase
mixs='0123456789'+lowercase+uppercase+'##$%&*'
In the mixs variable, there will be lowercase letters twice, I don't think you want this. I think what you want is this (because lowercase letters are already included in your uppercase variable):
mixs='0123456789'+uppercase+'##$%&*'
I am writing a chess program and in my code I keep running into this error in my function. this is occurring in the third to last line.
The full traceback is:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\jacob\AppData\Local\Programs\Thonny\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
File "C:\Users\jacob\Desktop\chess2.py", line 96, in <lambda>
buttons=(tk.Button(self.boardframe, padx=10, text=self.placepieces(pos), borderwidth=0, bg=colour, relief="solid", font=self.piecefont, command=lambda position=pos: self.movepiece(position) ))
File "C:\Users\jacob\Desktop\chess2.py", line 73, in movepiece
if self.newsquare in movelist:
TypeError: argument of type 'NoneType' is not iterable
Where the buttons are defined:
def drawboard(self):
x=0
y=0
for column in range(self.n):
self.changecolours()
x=x+1
y=0
for row in range(self.n):
y=y+1
colour = self.colours[self.colourindex]
pos=(x,9-y)
buttons=(tk.Button(self.boardframe, padx=10, text=self.placepieces(pos), borderwidth=0, bg=colour, relief="solid", font=self.piecefont, command=lambda position=pos: self.movepiece(position) ))
buttons.grid(column=(x-1), row=(y-1), sticky="W"+"E"+"N"+"S" )
self.changecolours()
def movepiece(self, squareposition):
player=Game().player
turn=Game().turn
if self.square==(-10,-10):
self.square=squareposition
if self.square in player.position.values()==True:
for key in player.position:
pieceposition=player.position.get(key)
if self.square==pieceposition:
self.piece=key
break
else:
pass
else:
self.gamelabel.config(text="Error no " +str(turn)+" piece on this square please try again")
self.square==(-10,-10)
else:
self.newsquare=squareposition
if self.newsquare==self.square:
self.square=(-10,-10)
self.newsquare=(-11,-11)
self.gamelabel.config(text=str(turn)+" to move")
else:
movelist=player.moves.get(self.piece)
if self.newsquare in movelist:
self.square=(-10,-10)
self.newsquare=(-11,-11)
It looks like your getting this error because the key you are trying to access in the player.moves either does not exist, or the value of the key is None. You can get around this by performing a sanity check to make sure movelist is not None
if movelist and self.newsquare in movelist:
self.square=(-10,-10)
self.newsquare=(-11,-11)
I would like to put a variable in a Tkinter label that prints out the value of the variable 'x'.
I tried to follow the example from the Tkinter documentation but it still seems to give me a trace error 'in second_click lblx2.place(window)'
x = max(numbers)
y = min(numbers)
z = sum(numbers)
a = float(z / len(numbers))
var_x = StringVar()
var_x.set(x)
lblx2 = Label(window, textvariable=var_x, font=('Arial Bold', 15), bg='blue', fg='red')
lblx2.place(window)
I expect it to just place the number on my window like regular text but it does not print anything.
The full error:
Exception in Tkinter callback
Traceback (most recent call last):
File "REDACTED", line 1705, in __call__ return self.func(*args)
File "REDACTED", line 49, in <lambda> btn['command'] = (lambda: second_click())
File "REDACTED", line 102, in second_click lblx2.place(window)
File "REDACTED", line 2188, in place_configure
File "REDACTED", line 1320, in _options cnf = _cnfmerge(cnf)
File "REDACTED", line 104, in _cnfmerge for c in _flatten(cnfs):
TypeError: object of type 'Tk' has no len()
When I remove (window) from place, it stops giving the errors but still does not put the number on the window
I believe the error is that window is not a suitable parameter for a Label object. Instead, it is used to change the location of the element. You could either
turn it into this: lblx2.place(x=whatever,y=whatever) (note: replace whatever with the location)
or
Remove the whole line of code entirely as it's unnecessary
Don't see a problem. Please provide a full example, not just pieces of code one cannot simply run. Here is mine, that DOESN'T reproduce the issue, and it really doesn't get much simpler than this:
from tkinter import *
from random import random
x = random()
root = Tk()
var_x = StringVar()
var_x.set(x)
Label(root, textvariable=var_x).pack()
root.mainloop()
This code is part of a bigger program that uses the google Sheets API to get data from a cloud database (not really relevant, but a bit of context never hurt!)
I have this black of code in one python file named 'oop.py'
class SetupClassroom:
def __init__(self, arraynumber='undefined', tkroot='undefined'):
self.arraynumber = arraynumber
self.tkroot = tkroot
def setarraynumber(self, number):
from GUI_Stage_3 import showclassroom
self.arraynumber = number
print ('set array number:', number)
showclassroom()
def settkroot(self, tkrootinput):
self.tkroot = tkrootinput
self.tkroot has been assigned by another part of the code. This bit works, as I have already tested that it is being assigned, however, when I call 'self.tkroot' in another another file like this
def showclassroom():
from oop import SetupClassroom
username = current_user.username
classnumber = getnumberofuserclassrooms(username)
if SetupClassroom.arraynumber > classnumber:
errorwindow('you are not enrolled in that many classrooms!')
else:
classtoget = SetupClassroom.arraynumber
print('classtoget:', classtoget)
root = SetupClassroom.tkroot
name_label = Label(root, text=classtoget)
getclassroom(username, classtoget)
SetupClassroom = SetupClassroom
I get this error
Exception in Tkinter callback
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/tkinter/__init__.py", line 1705, in __call__
return self.func(*args)
File "/Users/jonathansalmon/PycharmProjects/Coursework_GUI/GUI_Stage2_better.py", line 176, in <lambda>
l0 = ttk.Button(teacher_root, text=button0text, command=lambda: (SetupClassroom.setarraynumber(SetupClassroom, number=button0text), SetupClassroom.settkroot(SetupClassroom, 'teacher_root')))
File "/Users/jonathansalmon/PycharmProjects/Coursework_GUI/oop.py", line 99, in setarraynumber
showclassroom()
File "/Users/jonathansalmon/PycharmProjects/Coursework_GUI/GUI_Stage_3.py", line 29, in showclassroom
root = SetupClassroom.tkroot
AttributeError: type object 'SetupClassroom' has no attribute 'tkroot'
I tried setting it up in the python console and it worked, so I have no idea what the problem is.
If anyone could help, it would be very much appreciated
Thanks!
John
You should create an instance of class, it will create the attribute in __init__, self.tkroot is the attribute of instance not class:
setupClassroom = SetupClassroom()
print(setupClassroom.tkroot)
Hope that will help you.
I've been trying to get my Tkinter wrapper (specialised to make a game out of) to work, but it keeps throwing up an error when it tries to draw a rectangle.
Traceback:
Traceback (most recent call last):
File "C:\Users\William\Dropbox\IT\Thor\test.py", line 7, in <module>
aRectangle = thorElements.GameElement(pling,rectangleTup=(True,295,195,305,205,"blue"))
File "C:\Users\William\Dropbox\IT\Thor\thorElements.py", line 79, in __init__
self.rectangle = self.area.drawRectangle(self)
File "C:\Python33\lib\tkinter\__init__.py", line 1867, in __getattr__
return getattr(self.tk, attr)
AttributeError: 'tkapp' object has no attribute 'drawRectangle'
The sections of the code that are relevant to the question,
class GameElement():
def __init__(self,area,rectangleTup=(False,12,12,32,32,"red")):
self.area = area
self.lineTup = lineTup #Tuple containing all the data needed to create a line
if self.lineTup[0] == True:
self.kind = "Line"
self.xPos = self.lineTup[1]
self.yPos = self.lineTup[2]
self.line = self.area.drawLine(self)
And here's the actual method that draws the rectangle onto the canvas (in the class that manages the Canvas widget), earlier in the same file:
class Area():
def drawLine(self,line):
topX = line.lineTup[1]
topY = line.lineTup[2]
botX = line.lineTup[3]
botY = line.lineTup[4]
colour = line.lineTup[5]
dashTuple = (line.lineTup[6][0],line.lineTup[6][1])
return self.canvas.create_line(topX,topY,botX,botY,fill=colour,dash=dashTuple)
print("Drew Line")
All input is greatly appreciated.
The error message is meant to be self explanatory. When it says AttributeError: 'tkapp' object has no attribute 'drawRectangle', it means that you are trying to do tkapp.drawRectangle or tkapp.drawRectangle(...), but tkapp doesn't have an attribute or method named drawRectangle.
Since your code doesn't show where you create tkapp or how you created it, or where you call drawRectangle, it's impossible for us to know what the root of the problem is. Most likely it's one of the following:
tkapp isn't what you think it is
you have a typo, and meant to call drawLine rather than drawRectangle,
you intended to implement drawRectangle but didn't