I have the following two files:
main.py
import tkinter as tk
import hashlib, json
from tkml import element
f = open("users.json", "r")
users = json.loads(f.read())
f.close()
f = open("users.json", "w")
window = tk.Tk()
window.title("Hello wold")
window.geometry("600x800")
pages = {}#initialize this variable
currentPage = ""#initialize this variable
def goTo(pageName):
global pages, currentPage
pages[currentPage].unloads()
pages[pageName].load(window)
currentPage = pageName
pages = {
"SignInOrCreateAccount": element(tk.Frame(),
[
element(tk.Button(text = "sign in", command = lambda : goTo("SignIn")), [], lambda widget, parent : widget.place(parent, anchor = "NW", relx = 0, rely = 0, x = 30, y = 30)),
element(tk.Button(text = "create account", command = lambda : goTo("CreateAccount")), [], lambda widget, parent : widget.place(parent, anchor = "NE", relx = 0, rely = 0, x = 30, y = 30))
], lambda widget, parent: widget.place(parent, relx = 0, rely = 0, relwidth = 1, relheight = 1))
}
currentPage = "SignInOrCreateAccount"
pages[currentPage].loads(window)
def saveUsersChanges():
global f, users
json.dump(users, f)
def attemptSignIn(username, password):
if username in users:
if hashlib.sha256(password.encode()).hexdigest() == users[username]["password"]:
pass # left off here
def onClose():
global f
saveUsersChanges()
f.close()
window.protocol("WM_DELETE_WINDOW", onClose())
tk.mainloop()
and tkml.py
class element:
def __init__(self, widget , children, load, unload = lambda widget: widget.place_forget()):
self.widget = widget # the tk widget
self.load = load # load just this widget using lambda function
self.unload = unload
self.children = children # child widgets
def loads(self, parent): # load this widget and all child widgets
self.load(self.widget, parent)
for child in self.children:
child.loads(self)
def unloads(self): # unloads widget and all child widgets
self.unload(self.widget)
for child in self.children:
child.unloads()
when I attempt to run it I get a very long error:
Traceback (most recent call last):
File "main.py", line 27, in <module>
pages[currentPage].loads(window)
_cnfmerge: fallback due to: 'element' object is not iterable
Traceback (most recent call last):
File "/usr/lib/python3.8/tkinter/__init__.py", line 111, in _cnfmerge
cnf.update(c)
TypeError: 'element' object is not iterable
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "main.py", line 27, in <module>
pages[currentPage].loads(None)
File "/home/runner/Phoebe-Hacking-Puzzle/tkml.py", line 10, in loads
child.loads(self)
File "/home/runner/Phoebe-Hacking-Puzzle/tkml.py", line 8, in loads
self.load(self.widget, parent)
_cnfmerge: fallback due to: 'element' object is not iterable
Traceback (most recent call last):
File "/usr/lib/python3.8/tkinter/__init__.py", line 111, in _cnfmerge
cnf.update(c)
TypeError: 'element' object is not iterable
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "main.py", line 27, in <module>
pages[currentPage].loads(window)
File "/home/runner/Phoebe-Hacking-Puzzle/tkml.py", line 10, in loads
child.loads(self)
File "/home/runner/Phoebe-Hacking-Puzzle/tkml.py", line 8, in loads
self.load(self.widget, parent)
Traceback (most recent call last):
File "main.py", line 27, in <module>
pages[currentPage].loads(window)
File "/home/runner/Phoebe-Hacking-Puzzle/tkml.py", line 8, in loads
self.load(self.widget, parent)
File "main.py", line 24, in <lambda>
], lambda widget, parent: widget.place(parent, relx = 0, rely = 0, relwidth = 1, relheight = 1))
File "/usr/lib/python3.8/tkinter/__init__.py", line 2439, in place_configure
self.tk.call(
_tkinter.TclError: unknown option "-bd"
I have tried debugging by wading into tkinter's source code and while I have successfully tracked down the line of code that the error comes from, I have no idea where this -bd has come from or what it means. I am new to tkinter, always having used pygame in the past, so there is a good chance I am simply using a function wrong, I would appreciate any help anyone can provide.
PS: I am running my code off repl.it if that makes any difference.
Related
from tkinter import *
window = Tk()
window.title('Pomodoro timer')
window.config(padx=100, pady=50)
canvas = Canvas(width=200, height=224)
tomato_img = PhotoImage(file="C:/vscode/tomato.png")
canvas.create_image(102, 112, image=tomato_img)
Canvas.create_text(102, 112, text='00:00')
canvas.pack()
window.mainloop()
This is the code that I'm working on
when I'm trying to add two integers for x and y co-ordinates to the Canvas.create_text function, it gives me this error
Traceback (most recent call last):
File "C:\pycharm and thonny\pythonProject1\main.py", line 26, in <module>
Canvas.create_text(102, 112, text='00:00')
File "C:\Users\ASUS\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 2810, in create_text
return self._create('text', args, kw)
AttributeError: 'int' object has no attribute '_create'
Alrighty so this is the error I get:
AttributeError: 'DES' object has no attribute 'summary_output'
So this is what I am trying to do.
When I am on this frame, I am creating a text variable that is then sent to a set class.
class upload_csv(Frame):
def __init__(self, master):
self.master = master
self.frame = tk.Frame(self.master, width=250, height=160, bg='white')
self.upload_csv_btn = Button(
self.frame,
text="Add Data Source",
fg="DodgerBlue4",
font=("Graph Type", 15),
height=1, width=20,
borderwidth=2,
relief="groove",
command=self.upload)
self.upload_csv_btn.place(x=10, y=10)
self.frame.pack()
def upload(self):
global text
self.xvalues = []
self.yvalues = []
self.xyvalues = []
self.header = []
filename = filedialog.askopenfilename()
if len(filename) != 0:
print('Selected:', filename)
with open(filename) as file:
csvreader = csv.reader(file)
self.header.append(next(csvreader))
for row in csvreader:
if len(row) == 3:
self.xvalues.append(int(row[0]))
self.yvalues.append(int(row[1]))
self.xyvalues.append(int(row[2]))
text = (
self.header[0][0]+ ": " + str(self.xvalues).replace('[','').replace(']','') +
"\n\n" + self.header[0][1] + ": " + str(self.yvalues).replace('[','').replace(']','') +
"\n\n" + self.header[0][2] + ": " + str(self.xyvalues).replace('[','').replace(']',''))
elif len(row) == 2:
self.xvalues.append(row[0])
self.yvalues.append(row[1])
text = (
self.header[0][0] + ": " + str(self.xvalues).replace('[','').replace(']','') +
"\n\n" + self.header[0][1] + ": " + str(self.yvalues).replace('[','').replace(']',''))
# -------------------------------------------------------------------------
s = Set(text)
s.set_summary()
#-----------------------------------------------------------------------
Using the upload class, I am sending the variable by calling the set class, and calling the set_summary method. With this set class, I am setting the string as a an object item, that is then send to my DES class. I want this item to be set on a tk textbox element as a summary. I receive the text fine in the DES class, but I get the following error when trying to modify the summary element.
The error I get:
Traceback (most recent call last):
File "C:\Users\***\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "C:\Users\***\Documents\Workspace\***\***\view\upload_csv.py", line 115, in upload
s.set_summary()
File "C:\Users\***\Documents\Workspace\***\***\view\Set.py", line 14, in set_summary
s.set_summary_text()
File "C:\Users\***\Documents\Workspace\***\***\view\test.py", line 164, in set_summary_text
print(self.summary_output)
AttributeError: 'DES' object has no attribute 'summary_output'
My set class:
class Set:
def __init__ (self, summary):
self.summary = summary
def set_summary(self):
print(self.summary)
s = DES(self.summary)
s.set_summary_text()
My DES Class:
class DES(Frame):
def __init__(self, summary):
self.summary = summary
def createFrame(self, master):
self.frame = tk.Frame(master, width=750, height=968,bg='white')
self.summary_output = tk.Text(
self.frame,
height=8,
width=78,
bg="gray95",
borderwidth=2,
relief="groove",
font=("Arial", 12))
self.summary_output.configure(state='disabled')
self.summary_output.place(x=20, y=610)
self.frame.pack()
def set_summary_text(self):
print(self.summary)
print(self.summary_output)
self.summary_output.configure(state='normal')
self.summary_output.delete('1.0', END) # Remote all text
self.summary_output.insert('end',self.summary)
self.summary_output.configure(state='disabled') #Make text widget read only
def main():
global root
root = tk.Tk()
# app = DES(root)
# app = DES.createFrame(root)
s = DES("")
s.createFrame(root)
root.mainloop()
if __name__ == '__main__':
main()
Edit:
So after trying the answer I got the following error, all I did was add the suggestion:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\***\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "C:\Users\***\Documents\Workspace\\***\\***\view\upload_csv.py", line 115, in upload
s.set_summary()
File "C:\Users\\***\Documents\Workspace\\***\view\Set.py", line 22, in set_summary
s.createFrame(root)
File "C:\Users\\***\Documents\Workspace\\***\view\test.py", line 120, in createFrame
self.canvas.draw() # Create the graph canvas
File "C:\Users\\***\AppData\Local\Programs\Python\Python39\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 11, in draw
self._master.update_idletasks()
AttributeError: 'str' object has no attribute 'update_idletasks'
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\\***\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "C:\Users\\***\AppData\Local\Programs\Python\Python39\lib\site-packages\matplotlib\backends\_backend_tk.py", line 235, in filter_destroy
self._master.update_idletasks()
AttributeError: 'str' object has no attribute 'update_idletasks'
So I remove the matplot graph and got this error:
So maybe the graph is interfering? Im not sure, I need the graph.
The summary_output in DES class, will be defined in the
createFrame method.
You first instatiated from the DES class in the Set.set_summary()
method and then called the set_summary_text() method, which it uses
the summary_output. That's not correct, since the summary_output has not been defined, yet.
You should first, call the createFrame() method to define the
summary_output attribute and then call the set_summary_text() to
use summary_output.
Do something like this, in the Set class:
class Set:
def __init__ (self, summary):
self.summary = summary
def set_summary(self):
global root
print(self.summary)
s = DES(self.summary)
s.createFrame(root)
s.set_summary_text()
Or do whatever you think it's best for you, but you should define the summary_output first, and then print or use it.
I'm attempting to make a simple platformer game, however, I can't show the "Game Over" message because tkinder, and more specifically, tkfont, or tkinder.font, is a module, and cannot be called.
Code here. The full traceback is:
Traceback (most recent call last):
File "C:\Users\iD Student\Desktop\Connor M\Endless platformer.py", line
31, in <module>
helv36 = tkinter.font(family="Helvetica",size=36,weight="bold")
TypeError: 'module' object is not callable
tkinter.font.Font throws this traceback:
Traceback (most recent call last):
File "C:\Users\iD Student\Desktop\Connor M\Endless platformer.py", line
31, in <module>
helv36 = tkinter.font.Font(family="Helvetica",size=36,weight="bold")
File "C:\Python35\lib\tkinter\font.py", line 93, in __init__
tk.call("font", "create", self.name, *font)
AttributeError: 'NoneType' object has no attribute 'call'
which I assume to be an error in tkinter itself. Relevant code:
import tkinter
from tkinter.font import *
helv36 = tkinter.font.Font(family="Helvetica",size=36,weight="bold")
def draw_text(display_string, font, surface, x_pos, y_pos):
text_display = font.font(display_string, 1, (0, 0, 0))
surface.blit(text_display, (x_pos, y_pos))
#Ends the game if the player dies
if y >640:
endgame = True
if endgame:
draw_text("GAME OVER", helv36, screen, 50, 50)
You can't create a font until after you've created a root window.
I don't know why this is giving me an attribute error. I want my blah() function to shuffle the cards. I'm calling the builtin function shuffle() from random.
Error:
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1489, in __call__
return self.func(*args)
File "gui1.py", line 105, in blah
shuffle(cards)
AttributeError: Button instance has no __call__ method
Here's the code snippet:
def blah():
global card_count
global path
shuffle(cards)
card_count = 0
path = generate_paths(cards)
print "Cards Shuffled"
shuffle = Button(frame_buttons, text = "SHUFFLE",height = 2, width = 10,command =blah)
shuffle.grid(row = 2 , padx = 40, pady = 40)
shuffle is the name of the function in random. However, it's also the name of the Button. Change the Button's name to something like shuffle_button and you should be fine.
I'm writing a function to convert and display an image to negative, when i call the function i get this error message:
Traceback (most recent call last):
File "C:/Users/User/PycharmProjects/Librophyton/Procdeimagenes/test.py",line 32, in <module>
makeNegative(dude)
File "C:\Python34\lib\ImageProcess.py", line 16, in makeNegative
old = FileImage(imageFile)
File "C:\Python34\lib\cImage.py", line 398, in __init__
super(FileImage, self).__init__(fname = thefile)
File "C:\Python34\lib\cImage.py", line 241, in __init__
self.loadImage(fname)
File "C:\Python34\lib\cImage.py", line 270, in loadTkImage
sufstart = fname.rfind('.')
AttributeError: 'FileImage' object has no attribute 'rfind'
Here is the function:
def makeNegative(imageFile):
window = ImageWin("Proceso de imagen", 1000-100, 900)
old = FileImage(imageFile)
old.draw(window)
window.exitOnClick()
w = old.getWidth()
h = old.getHeight()
new = EmptyImage(w,h)
for row in range(h):
for col in range(w):
pixelviejo = old.getPixel(col,row)
pixelnuevo = pixelNeg(pixelviejo)
new.setPixel(col, row, pixelnuevo)
new.setPosition(w+1, 0)
new.draw(window)
window.exitOnClick()
And here is the funciton call:
dude = FileImage("factores_de_conversion.gif" )
makeNegative(dude)
Any idea how to solve this? or how should i modify the module?