Storing frames in list - python

I'm trying to store frames in a list so i can get my widgets 3 by 3 on top of each other whit a small space in between them
But i can't seem to make it work.
Code:
self.cboCombo = []
self.frame_type = []
for x in range(7):
self.cboCombo.append([])
for y in range(3):
self.cboCombo[x].append([])
for i in range(7):
self.frame_type.append(i)
self.frame_type[i] = Frame(self.frame_type)
self.frame_type[i].pack(side=TOP, expand=1, ipady= 11)
self.cboCombo[i][0] = ttk.Combobox(self.frame_type[i], values=self.valCombo, textvariable=self.varCombo[1][0])
self.cboCombo[i][0].pack(padx= 5)
self.cboCombo[i][1] = ttk.Combobox(self.frame_type[i], values=self.valCombo, textvariable=self.varCombo[1][1])
self.cboCombo[i][1].pack(padx= 5)
self.cboCombo[i][2] = ttk.Combobox(self.frame_type[i], values=self.valCombo, textvariable=self.varCombo[1][2])
self.cboCombo[i][2].pack(padx= 5)
Error message:
File "File.py", line 89, in __init__
self.frame_type[i] = Frame(self.frame_type)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 2453, in __init__
Widget.__init__(self, master, 'frame', cnf, {}, extra)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1965, in __init__
BaseWidget._setup(self, master, cnf)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1943, in _setup
self.tk = master.tk
AttributeError: 'list' object has no attribute 'tk'
Is there a solution to this or another way to get it done?
Thanks

Following the Tkinter docs:
w = Frame ( master, option, ... )
Parameters:
master: This represents the parent window.
Your self.frame_type doesn't look like object represents the parent window.

Related

Expected type 'Canvas', got 'int' instead

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'

AttributeError: object has no attribute?

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.

Kivy Button: on_press function called before its being pressed

Im writing a Sudoku solver UI in Kivy.
I wanted to add a button, which upon being pressed, solves the Grid. The function works, although when I assign it to a button as the on_press function, it somehow runs before the button is pressed. I've tried everything. I get an Assertion Error. When I just use the solve function, it works. Not with the button, though.
Thank you for helping.
This is the __init__ function:
class SudokuGrid(GridLayout):
def __init__(self, **kwargs):
super(SudokuGrid, self).__init__(**kwargs)
self.grid = [[8,7,0, 0,0,0, 0,0,0],
[0,0,0, 9,0,0, 0,0,4],
[0,2,0, 7,0,0, 1,0,5],
[0,0,9, 6,0,0, 0,3,0],
[0,0,0, 0,0,0, 0,0,9],
[0,0,6, 5,4,0, 0,0,0],
[6,9,0, 0,0,0, 7,0,0],
[2,0,0, 0,0,7, 4,0,0],
[0,0,0, 3,0,0, 0,1,0]]
self.add_widget(Button(on_press=self.solve()))
self.cols = 3
self.rows = 4
self.load_grid()
And this my solve function:
def solve(self):
for x in range(9):
for y in range(9):
if self.grid[y][x] == 0:
for n in range(1,10):
if self.possible(y,x,n):
self.grid[y][x] = n
self.solve()
self.grid[y][x] = 0
return
self.load_grid()
print(np.matrix(self.grid))
I know that the function is run, because before the App terminates, I get the output of the solved Grid.
This is the Traceback:
Traceback (most recent call last):
File "C:\Users\victo\Desktop\portfolio\Sudoku\sudoku_app.py", line 217, in <module>
sudoku_game.run()
File "C:\Users\victo\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\app.py", line 829, in run
root = self.build()
File "C:\Users\victo\Desktop\portfolio\Sudoku\sudoku_app.py", line 205, in build
self.sudoku_grid = SudokuGrid()
File "C:\Users\victo\Desktop\portfolio\Sudoku\sudoku_app.py", line 73, in __init__
self.add_widget(Button(on_press=self.solve()))
File "C:\Users\victo\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\behaviors\button.py", line 121, in __init__
super(ButtonBehavior, self).__init__(**kwargs)
File "C:\Users\victo\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\label.py", line 318, in __init__
super(Label, self).__init__(**kwargs)
File "C:\Users\victo\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\widget.py", line 369, in __init__
self.bind(**on_args)
File "kivy\_event.pyx", line 419, in kivy._event.EventDispatcher.bind
AssertionError: None is not callable
Okay so i figured it out. Erik said in his comment:
Try on_press=self.solve in stead of on_press=self.solve()
which worked, although I got another Error. I had one too many positional arguments for solve(). I fixed it by defining my method as:
def solve(self, *args)
Everything works now.

Can't find tkinter AttributeError

I am writing a code for banking system using python and Tkinter. When I run the program I encounter a few errors. Could someone please help me to figure this out. I have done research about it, but can't find a solution to the problem.
Here is the error:
...File "C:\Users\stjur\AppData\Local\Programs\Python\Python36-32\lib\tkinter\__init__.py", line 2256, in _setup
self.tk = master.tk
AttributeError: 'function' object has no attribute 'tk'
And here is my code:
from tkinter import *
root=Tk()
root.title('Avis Banking System')
def win1():
global balance
balance=600
global root
global tries
root=Tk()
root.title('Avis banking system')
entry_1Var=StringVar()
entry_2Var=StringVar()
tries=0
tries=0
def CheckPass():
global tries
if (tries<3):
textvalue=entry_1Var.get()
textvalue=entry_2Var.get()
if textvalue!=('John123') and textvalue!=('Secret'):
tries+=1
label3=Label(root,text='Try again')
label.grid(row=3,column=1,sticky=W,padx=7)
else:
win2()
if (tries==3):
label4=Label(root,text='Used all attempts, entry blocked')
label4.grid(row=3,column=1, sticky=W,padx=7)
entry_1Var=StringVar()
entry_2Var=StringVar()
b1=Button(root,text='Login',width=5,command=CheckPass)
b1.grid(row=1,column=10,sticky='e'+'w',padx=7)
b2=Button(root,text='Reset',width=5,)
b2.grid(row=2,column=10,sticky='e'+'w',padx=7)
l1=Label(root,text='Username:').grid(row=1,padx=7,pady=5,sticky='we')
l2=Label(root,text='Password:').grid(row=2,padx=7,pady=5,sticky='we')
e1=Entry(root,width=30,textvariable=entry_1Var)
e1.grid(row=1,column=1,sticky='e'+'w',columnspan=2)
e2=Entry(root,show='*',width=30,textvariable=entry_2Var)
e2.grid(row=2,column=1,sticky='e'+'w',columnspan=2)
logLabel=Label(root,text='Login',font='bold',fg='Grey')
logLabel.grid(row=0,padx=5,pady=5)
check=Checkbutton(root,text='Keep me logged in')
ckeck.grid(row=4,column=1,sticky=W,pady=5)
if (tries==3):
win2
def win2():
#this is the child window of the main window.
win2=Toplevel(root)
win2.minsize(width=400,height=400)
win2.title("Main Menu")
#Label for the the main menu
lb=Label(win2,text='N&E Scotland Bank\nMain Menu:',bg='#e6e6e6',height=6).pack(fill=X)
btn_1=Button(win2,text='Make Deposit',width=15,height=2,command=win3).pack(pady=5)
btn_2=Button(win2,text='Withdrawal',width=15,height=2).pack(pady=5)
btn_3=Button(win2,text='Accounts',width=15,height=2).pack(pady=5)
btn_4=Button(win2,text='Balance',width=15,height=2).pack(pady=5)
btn_5=Button(win2,text='Exit',width=15,height=2).pack(pady=5)
def win3():#new window for the button make depost
win3=Tk()
win3.title('Make Deposit')
win3.minsize(width=400,height=120)
e1=IntVar()
e2=IntVar()
def MakeDeposit():
num2 = e2.get()
balance = int(num2)
num1 = e1.get()
depositAmount = int(num1)
while depositAmount<=0 or depositAmount%10!=0:
errorLabel = Label(win3,text="That was not a valid amount").grid(row=3,columnspan=5)
return#
textLabel = Label(win3,text=("Your new balance is:\n")).grid(row=3,columnspan=5)
newBalanceLabel = Label(win3,text=(balance+depositAmount)).grid(row=4,columnspan=5, pady=7)
l1=Label(win3,text='Deposit Amount:').grid(row=1,padx=7,pady=5,sticky='we')
l2=Label(win3,text='Balance:').grid(row=2,padx=7,pady=5,sticky='e')
b1=Butto(win3,text='Calculate',width=8,height=3,command=MakeDeposit).grid(row=1,column=10,sticky='e'+'w',padx=7,rowspan=2)
e1=Entry(win3,width=40)
e1.grid(row=1,column=1,sticky='e'+'w',columnspan=3)
e2=Entry(win3,width=40)
e2.grid(row=2,column=1,sticky='e'+'w',columnspan=3)
logLabel=Label(root,text='DEPOSIT',font='bold',fg='Grey').grid(row=0,padx=5,pady=5)
root.mainloop()
I can explain the error message. After fixing the formatting errors in my local copy, I got this:
Traceback (most recent call last):
File "F:\Python\mypy\tem.py", line 84, in <module>
l1=Label(win3,text='Deposit Amount:').grid(row=1,padx=7,pady=5,sticky='we')
File "C:\Programs\Python36\lib\tkinter\__init__.py", line 2760, in __init__
Widget.__init__(self, master, 'label', cnf, kw)
File "C:\Programs\Python36\lib\tkinter\__init__.py", line 2286, in __init__
BaseWidget._setup(self, master, cnf)
File "C:\Programs\Python36\lib\tkinter\__init__.py", line 2256, in _setup
self.tk = master.tk
AttributeError: 'function' object has no attribute 'tk'
The first, parent argument for any Widget creation call must be a widget. In
l1=Label(win3, ...
you passed the win3 function, which does not have a tk attribute.
For the future, please read about MCVEs.

Memory full Python plotting 3d

I'm getting some memory problems from plotting images in a loop. How do I delete the old ones?
Error:
Traceback (most recent call last):
File "C:\Users\Alex\Dropbox\code stuff\solarsystem.py", line 69, in <module>
fig = plt.figure()
File "C:\Python27\lib\site-packages\matplotlib\pyplot.py", line 343, in figure
**kwargs)
File "C:\Python27\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 79, in new_figure_manager
return new_figure_manager_given_figure(num, figure)
File "C:\Python27\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 106, in new_figure_manager_given_figure
canvas = FigureCanvasTkAgg(figure, master=window)
File "C:\Python27\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 225, in __init__
master=self._tkcanvas, width=w, height=h)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 3306, in __init__
Image.__init__(self, 'photo', name, cnf, master, **kw)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 3262, in __init__
self.tk.call(('image', 'create', imgtype, name,) + options)
TclError: not enough free memory for image buffer
Script:
count = 0
xy = bodies[0][2]
x = [[a[0] for a in bodies[0][2]]]
y = [[a[1] for a in bodies[0][2]]]
z = [[a[2] for a in bodies[0][2]]]
for i in range(1,nbodies):
x.append([a[0] for a in bodies[i][2]])
y.append([a[1] for a in bodies[i][2]])
z.append([a[2] for a in bodies[i][2]])
for j in range(0,len(bodies[0][2])-1,10):
Xc = [[x[0][j]]]
Yc = [[y[0][j]]]
Zc = [[z[0][j]]]
for k in range(1,nbodies):
Xc.append([x[k][j]])
Yc.append([y[k][j]])
Zc.append([z[k][j]])
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
for l in range(len(Xc)):
ax.scatter( Xc[l], Yc[l], Zc[l], c=(i/nbodies,i/nbodies,i/nbodies))
ax.axis([-400, 400, -400, 400])
ax.set_zlim(-400, 400)
pylab.savefig('images/img'+str(count))
pylab.clf()
count += 1
percent = (j/(len(bodies[0][2])-1.))*100
if percent % 10 ==0:
print percent
If you're generating a number of pictures, you need to not only call the
plt.clf()
function between figures, but also the
plt.close()
function between pictures (i.e. after the for j in range(0,len(bodies[0][2])-1,10):
loop completes)
You can delete the fig instance (when you're done with it) using
del fig
and you can delete the files with os.unlink
os.unlink('images/img'+str(count))

Categories