Self is not defined? - python

I am attempting to make a basic study clock as a learning exercise for Tkinter but I get an error when attempting run it saying self is not defined. Here is the error message.
Traceback (most recent call last):
File "productivityclock.py", line 6, in <module>
class gui(object):
File "productivityclock.py", line 113, in gui
while 0 < self.z:
NameError: name 'self' is not defined
Here is my code, I would really appreciate if someone could help me out, Thanks
from Tkinter import *
import time
root = Tk()
class gui(object):
def __init__(self, master):
self.frame = Frame(master)
self.frame.pack()
t_int = 0
b_int = 0
reps = 0
self.menu()
def menu(self):
self.button1 = Button(
self.frame, text="Set Time", command = self.set_time)
self.button2 = Button(
self.frame, text="Set Breaks", command = self.set_break)
self.button3 = Button(
self.frame, text="Set Intervals", command = self.set_reps)
self.button4 = Button(
self.frame, text="Start", command = self.timer)
self.button1.pack(side = LEFT)
self.button2.pack(side = LEFT)
self.button3.pack(side = LEFT)
self.button4.pack(side = LEFT)
def set_time(self):
self.button1.pack_forget()
self.button2.pack_forget()
self.button3.pack_forget()
self.button4.pack_forget()
self.l = Label(self.frame, text = "Enter the time of each study session (minutes)")
self.button = Button(
self.frame, text="Get", command=self.on_button1)
self.entry = Entry(self.frame)
self.button.pack(side = RIGHT)
self.entry.pack(side = LEFT)
self.l.pack(side = LEFT)
def set_break(self):
self.button1.pack_forget()
self.button2.pack_forget()
self.button3.pack_forget()
self.button4.pack_forget()
self.l = Label(self.frame, text = "Enter the time of each break (minutes)")
self.button = Button(
self.frame, text="Get", command=self.on_button2)
self.entry = Entry(self.frame)
self.button.pack(side = RIGHT)
self.entry.pack(side = LEFT)
self.l.pack(side = LEFT)
def set_reps(self):
self.button1.pack_forget()
self.button2.pack_forget()
self.button3.pack_forget()
self.button4.pack_forget()
self.l = Label(self.frame, text = "Enter the amount of study sessions (minutes)")
self.button = Button(
self.frame, text="Get", command=self.on_button3)
self.entry = Entry(self.frame)
self.button.pack(side = RIGHT)
self.entry.pack(side = LEFT)
self.l.pack(side = LEFT)
def on_button1(self):
x = self.entry.get()
self.t_int = x
print self.t_int
self.button.pack_forget()
self.entry.pack_forget()
self.l.pack_forget()
self.menu()
def on_button2(self):
x = self.entry.get()
self.b_int = x
print self.b_int
self.button.pack_forget()
self.entry.pack_forget()
self.l.pack_forget()
self.menu()
def on_button3(self):
x = self.entry.get()
self.reps = x
print self.reps
self.button.pack_forget()
self.entry.pack_forget()
self.l.pack_forget()
self.menu()
def timer(self):
x = self.t_int
y = self.b_int
self.z = self.reps
while 0 < self.z:
while x > 0:
time.sleep(60)
n = Label(self.frame, text = "You have %r minutes left in your session") % x
n.pack(side = LEFT)
x = x - 1
n.pack_forget
while y > 0:
time.sleep(60)
self.e = Label(self.frame, text = "You have %r minutes left in your break") % y
self.e.pack(side = LEFT)
self.y = self.y - 1
self.e.pack_forget()
z = z - 1
x = self.t_int
y = self.b_int
app = gui(root)
root.mainloop()

Yes, at line 113, while 0 < self.z: is not properly indented, and all the lines below it.

Related

failed to resolve some method of tkinter

I am creating 2048 game on python with tkinter but I have a issue
I don't know what is wrong in left, right, up and down methods created in PageOne class.
In another class (StartPage), bind function calls these methods but this don't work
So I don't know how toresolve the mistakes, in bind functions or in the left, right, up and down methods?
In particular I get this error when I press the right key:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\fabio\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1921, in __call__
return self.func(*args)
File "C:\Users\fabio\PycharmProjects\2048gametk\2048gametk.py", line 198, in right
self.reverse()
AttributeError: 'Event' object has no attribute 'reverse'
And similar error for the other key (up, left and down):
Traceback (most recent call last):
File "C:\Users\fabio\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1921, in __call__
return self.func(*args)
File "C:\Users\fabio\PycharmProjects\2048gametk\2048gametk.py", line 208, in up
self.transpose()
AttributeError: 'Event' object has no attribute 'transpose'
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\fabio\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1921, in __call__
return self.func(*args)
TypeError: PageOne.left() missing 1 required positional argument: 'event'
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\fabio\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1921, in __call__
return self.func(*args)
File "C:\Users\fabio\PycharmProjects\2048gametk\2048gametk.py", line 218, in down self.transpose()
AttributeError: 'Event' object has no attribute 'transpose'
The left one is different because i put event instead of event = None as argument in the left module.
A small problem concern the score_frame that appears also in the StartPage and not only in the PageOne, so i don't know how to combine the frames on the code
Below you can find the entire code
Can anyone help me?
Thanks in advance
import os
import random
import sys
import tkinter as tk
from math import floor
class MyButton(tk.Button):
def __init__(self, *args, **kwargs):
tk.Button.__init__(self, *args, **kwargs, bg='brown', fg='white',
font="Helvetica 12 bold", width=8, pady='1m')
self.pack(pady="3m")
class Game(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.title("2048 game")
self.dim = 4
self.main_grid = None
container = tk.Frame(self, width=500, height=600)
container.grid(pady=(100, 0))
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage, PageOne):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(StartPage)
self.bind("<Left>", PageOne.left)
self.bind("<Right>", PageOne.right)
self.bind("<Up>", PageOne.up)
self.bind("<Down>", PageOne.down)
self.mainloop()
def show_frame(self, controller): #page_name al posto di controller
frame = self.frames[controller]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.dim = controller.dim
label = tk.Label(self, text="2048", font="Helvetica 48 bold", fg="orange")
label.pack(side="top", fill="x")
button1 = MyButton(self, text="3x3", command=self.dim_3)
button1.pack()
button1.bind("<Return>", self.dim_3)
button2 = MyButton(self, text="4x4", command=self.dim_4)
button2.focus_force()
button2.pack()
button2.bind("<Return>", self.dim_4)
button3 = MyButton(self, text="5x5", command=self.dim_5)
button3.pack()
button3.bind("<Return>", self.dim_5)
button4 = MyButton(self, text="8x8", command=self.dim_8)
button4.pack()
button4.bind("<Return>", self.dim_8)
def dim_3(self):
self.dim = 3
self.controller.show_frame(PageOne)
def dim_4(self):
self.dim = 4
self.controller.show_frame(PageOne)
def dim_5(self):
self.dim = 5
self.controller.show_frame(PageOne)
def dim_8(self):
self.dim = 8
self.controller.show_frame(PageOne)
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.matrix = None
self.score = None
self.cells = []
for i in range(self.controller.dim):
row = []
for j in range(self.controller.dim):
cell_frame = tk.Frame(self, bg="light grey",
width=500 / self.controller.dim, height=500 / self.controller.dim)
cell_frame.grid(row=i+10, column=j, padx=10 / self.controller.dim, pady=10 / self.controller.dim)
cell_number = tk.Label(self, bg="light grey")
cell_number.grid(row=i+10, column=j)
cell_data = {"frame": cell_frame, "number": cell_number}
row.append(cell_data)
self.cells.append(row)
score_frame = tk.Frame(controller.main_grid)
score_frame.place(relx=0.5, y=50, anchor="center")
tk.Label(score_frame, text="Score", font="Helvetica 18 bold").grid(row=0)
self.score_label = tk.Label(score_frame, text="0", font="Helvetica 24 bold")
self.score_label.grid(row=1)
self.start_game()
def start_game(self):
self.matrix = [[0] * self.controller.dim for _ in range(self.controller.dim)]
row = random.randint(0, self.controller.dim - 1)
col = random.randint(0, self.controller.dim - 1)
self.matrix[row][col] = 2
self.cells[row][col]["frame"].configure(bg="white")
self.cells[row][col]["number"].configure(bg="white", fg="black", font="Helvetica 24 bold", text="2")
while self.matrix[row][col] != 0:
row = random.randint(0, self.controller.dim - 1)
col = random.randint(0, self.controller.dim - 1)
self.matrix[row][col] = 2
self.cells[row][col]["frame"].configure(bg="white")
self.cells[row][col]["number"].configure(bg="white", fg="black", font="Helvetica 24 bold", text="2")
self.score = 0
# move all numbers on the left side
def stack(self):
new_matrix = [[0] * self.controller.dim for _ in range(self.controller.dim)]
for i in range(self.controller.dim):
fill_pos = 0
for j in range(self.controller.dim):
if self.matrix[i][j] != 0:
new_matrix[i][fill_pos] = self.matrix[i][j]
fill_pos += 1
self.matrix = new_matrix
# sum numbers horizontally and combine equal numbers
def combine(self):
for i in range(self.controller.dim):
for j in range(self.controller.dim - 1):
if self.matrix[i][j] != 0 and self.matrix[i][j] == self.matrix[i][j + 1]:
self.matrix[i][j] *= 2
self.matrix[i][j + 1] = 0
self.score += self.matrix[i][j]
# this function reverses the order of each row
def reverse(self):
new_matrix = []
for i in range(self.controller.dim):
new_matrix.append([])
for j in range(self.controller.dim):
new_matrix[i].append(self.matrix[i][self.controller.dim - 1 - j])
self.matrix = new_matrix
def transpose(self):
new_matrix = [[0] * self.controller.dim for _ in range(self.controller.dim)]
for i in range(self.controller.dim):
for j in range(self.controller.dim):
new_matrix[i][j] = self.matrix[j][i]
self.matrix = new_matrix
def add_number(self):
if any(0 in row for row in self.matrix):
row = random.randint(0, self.controller.dim - 1)
col = random.randint(0, self.controller.dim - 1)
while self.matrix[row][col] != 0:
row = random.randint(0, self.controller.dim - 1)
col = random.randint(0, self.controller.dim - 1)
self.matrix[row][col] = random.choice([2, 2, 2, 2, 4])
def update_GUI(self):
for i in range(self.controller.dim):
for j in range(self.controller.dim):
cell_value = self.matrix[i][j]
if cell_value == 0:
self.cells[i][j]["frame"].configure(bg="light grey")
self.cells[i][j]["number"].configure(bg="light grey", text="")
else:
self.cells[i][j]["frame"].configure(bg=NUMBER_COLOR[cell_value])
self.cells[i][j]["number"].configure(bg=NUMBER_COLOR[cell_value], fg="black",
font="Helvetica 24 bold", text=str(cell_value))
self.score_label.configure(text=self.score)
self.update_idletasks()
self.game_over()
def left(self, event):
self.stack()
self.combine()
self.stack()
self.add_number()
self.update_GUI()
self.game_over()
def right(self, event=None):
self.reverse()
self.stack()
self.combine()
self.stack()
self.reverse()
self.add_number()
self.update_GUI()
self.game_over()
def up(self, event=None):
self.transpose()
self.stack()
self.combine()
self.stack()
self.transpose()
self.add_number()
self.update_GUI()
self.game_over()
def down(self, event=None):
self.transpose()
self.reverse()
self.stack()
self.combine()
self.stack()
self.reverse()
self.transpose()
self.add_number()
self.update_GUI()
def horiz_moves(self):
for i in range(self.controller.dim):
for j in range(self.controller.dim - 1):
if self.matrix[i][j] == self.matrix[i][j + 1]:
return True
return False
def vert_moves(self):
for i in range(self.controller.dim - 1):
for j in range(self.controller.dim):
if self.matrix[i][j] == self.matrix[i + 1][j]:
return True
return False
def number(self):
if self.controller.dim == 3:
return 8
elif self.controller.dim == 4:
return 2048
elif self.controller.dim == 5:
return 8192
else:
return 16384
def restart(self):
self.bind("<Return>", os.execl(sys.executable, sys.executable, *sys.argv))
def game_over(self):
tk.Frame(self).place(relx=0.5, rely=0.5, anchor="center")
if not any(0 in row for row in self.matrix) and not self.horiz_moves() and not self.vert_moves():
top = tk.Toplevel()
top.geometry("300x100")
top.title("toplevel")
l2 = tk.Label(top, text="Game Over\n What do you want do?",
fg="white", font="Helvetica 12 bold")
l2.pack()
tk.Button(top, text="Restart", bg="green",
fg="white", font="Helvetica 10 bold",
command=self.restart).pack(side='left')
tk.Button(top, text="Quit", bg="red",
fg='white', font="Helvetica 10 bold", command=self.bind("<Return>", quit)).pack(side="right")
elif any(self.number() in row for row in self.matrix):
top = tk.Toplevel()
top.geometry("180x100")
top.title("toplevel")
l2 = tk.Label(top, text="You Win!\n What do you want do?", font="Helvetica 12 bold")
l2.pack()
tk.Button(top, text="Restart", bg="green",
fg="white", font="Helvetica 10 bold",
command=self.restart).pack(side='left')
tk.Button(top, text="Quit", bg="red",
fg='white', font="Helvetica 10 bold", command=self.bind("<Return>", quit)).pack(side="right")
def savegame(self):
f = open("savedata", "w")
line1 = " ".join(
[str(self.matrix[floor(x / self.controller.dim)][x % self.controller.dim])
for x in range(0, self.controller.dim ** 2)])
f.write(line1 + "\n")
f.write(str(self.controller.dim) + "\n")
f.write(str(self.score))
f.close()
def loadgame(self):
# self.score
# self.dim
# self.matrix
f = open("savedata", "r")
mat = (f.readline()).split(' ', self.controller.dim ** 2)
self.controller.dim = int(f.readline())
self.score = int(f.readline())
for i in range(0, self.controller.dim ** 2):
self.matrix[floor(i / self.controller.dim)][i % self.controller.dim] = int(mat[i])
f.close()
NUMBER_COLOR = {
2: "#fcefe6",
4: "#f2e8cb",
8: "#f5b682",
16: "#f29446",
32: "#ff775c",
64: "#e64c2e",
128: "#ede291",
256: "#fce130",
512: "#ffdb4a",
1024: "#f0b922",
2048: "#fad74d",
4096: "brown",
8192: "silver",
16384: "gold"
}
def main():
Game()
if __name__ == "__main__":
main()
Replace the code with the following:
self.bind("<Left>", self.frames[PageOne].left)
self.bind("<Right>", self.frames[PageOne].right)
self.bind("<Up>", self.frames[PageOne].up)
self.bind("<Down>", self.frames[PageOne].down)
The reason for your odd behavior is that you try to reach instances variables and methods but on the level of a class. It's not easy to explain in a few words, but you should research the difference between class an regular methods, the purpose of self and of course the documentation for classes and instances
Update
In order to make your dimensions work you need to create your matrix after you defined the dimensions, not when you initialize your Frame. The shortest way to achive this, is to create a function that is called when your dimension is defined.
In your PageOne you would do something like:
...
self.cells = []
def create_matrix(self):
for i in range(self.controller.dim):
...
score_frame = tk.Frame(self.controller.main_grid) #add self.
...
call this function when the user has chosen by (e.g):
def dim_3(self):
self.controller.dim = 3 #use self.controller dim
self.controller.frames[PageOne].create_matrix() #call create_matrix
self.controller.show_frame(PageOne)
and while you use the variable in your controller the following is not effective:
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
#self.dim = controller.dim
#is not a link to your var self.dim stores whats in controller.dim
Update2
in order to make your quit and restart work and with little improvements I have changed your code below. The code is left as an exercise since I still try to figure out the rules of the game. Happy codeing!
def restart(self):
for widget in self.winfo_children():
widget.destroy()
self.cells = []
self.controller.show_frame(StartPage)
def game_over(self):
tk.Frame(self).place(relx=0.5, rely=0.5, anchor="center")
if not any(0 in row for row in self.matrix) and not self.horiz_moves() and not self.vert_moves():
geo_string = "300x100"
title = "Game Over!"
text = "Game Over\n What do you want do?"
self.message(geo_string,title,text)
elif any(self.number() in row for row in self.matrix):
geo_string = "180x100"
title = "Congratulation!"
text = "You Win!\n What do you want do?"
self.message(geo_string,title,text)
def message(self, geo_string,title,text):
top = tk.Toplevel()
top.geometry(geo_string)
top.title(title)
l2 = tk.Label(top, text=text, font="Helvetica 12 bold")
l2.pack()
rbutton = tk.Button(top, text="Restart", bg="green",
fg="white", font="Helvetica 10 bold",
command=self.restart)
rbutton.bind('<ButtonRelease-1>',lambda e: self.controller.after(20,top.destroy))
rbutton.pack(side='left')
qbutton = tk.Button(top, text="Quit", bg="red",
fg='white', font="Helvetica 10 bold",
command=self.controller.destroy)
qbutton.pack(side="right")

I am working on a GUI which has several pages (I used different classes to show different pages). The problem I am facing is with navigation

I want to navigate to different pages of the GUI and on some pages, I need a timer if the timer expires then it will automatically redirect the user to Startpage. or if the user navigate then also timer will stop and the user will land on another page. The problem is that the timer of other pages is running in background and randomly takes user to start page. I am not able to figure out how to solve this
The code I developed is as follows:
import os
from itertools import cycle
import PIL.ImageTk, PIL.Image
import tkinter.font as font
import tkinter as tk
from tkinter import ttk
from tkinter.ttk import *
from tkinter import *
from tkinter import messagebox
import time
from time import sleep
from threading import Thread
LARGEFONT = ("Roboto", 35)
directory = r"C:\Users\mojave\tkinter\bg_images"
images = []
for filename in os.listdir(directory):
if filename.endswith(".jpg"):
images.append(os.path.join(directory,filename))
else:
continue
print(images)
#images = ["bg1.jpg", "bg2.jpg", "bg3.jpg"]
photos = cycle(PIL.ImageTk.PhotoImage(file=image) for image in images)
class tkinterApp(tk.Tk):
def __init__(self,*args,**kwargs):
tk.Tk.__init__(self,*args,**kwargs)
container = tk.Frame(self)
container.pack(side = "top", fill = "both", expand = True)
container.grid_rowconfigure(0,weight = 1)
container.grid_columnconfigure(0,weight = 1)
self.geometry('%dx%d' % (1366, 768))
self.frames = {}
for F in (StartPage, Page1, Page2):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0,column = 0, sticky = "nsew")
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
frame.event_generate("<<ShowFrame>>")
def get_page(self, page_class):
return self.frames[page_class]
# 1 second(s)
class StartPage(tk.Frame):
def __init__(self,parent,controller):
tk.Frame.__init__(self,parent)
self.photo = PhotoImage(file = r"recycle_icon.png")
self.photoimage = self.photo.subsample(20,20)
btnFont = font.Font(family='Roboto',size=32,weight='bold')
#app.geometry('%dx%d' % (1366, 768))
global displayCanvas
displayCanvas = ttk.Label(self)
displayCanvas.place(x=0,y=0)
self.after(10,lambda: slideShow())
label = ttk.Label(self,text="StartPage", font=LARGEFONT)
label.grid(row=0, column=4, padx=10, pady=10)
button1 = ttk.Button(self,text="Page 1", command=lambda: controller.show_frame(Page1))
button1.grid(row=1, column=1, padx=10, pady=10)
button2 = ttk.Button(self, text = "page 2",
command = lambda : controller.show_frame(Page2))
button2.grid(row = 2, column = 1,padx = 10,pady = 10)
start_btn = tk.Button(self,text="\nStart Recycle",height=650, width=300,image=self.photoimage,
compound= TOP, command=lambda: controller.show_frame(Page1), activebackground="green", background="red", foreground="white", bd=5)
start_btn['font'] = btnFont
#start_btn.pack(side=TOP)
start_btn.place(x=1010,y=60)
self.bind("<<ShowFrame>>", self.on_show_frame)
def on_show_frame(self,event):
print("start page is shown..")
class Page1(tk.Frame):
def __init__(self,parent,controller):
tk.Frame.__init__(self,parent)
#label = ttk.Label(self, text = "Page 1", font = LARGEFONT)
#label.grid(row = 0,column = 4,padx = 10,pady = 10)
lang_btnFont = font.Font(family='Roboto',size=32,weight='bold')
self.photo = PhotoImage(file = r"recycle_icon.png")
self.photoimage = self.photo.subsample(20,20)
self.img1 = PIL.ImageTk.PhotoImage(file=r'C:\\Users\\mojave\\tkinter\\bg_image.jpg')
displayCanvas1 = ttk.Label(self)
displayCanvas1.config(image=self.img1)
displayCanvas1.place(x=0,y=0)
lang_btn = tk.Button(self,text="English",height=300,
width=300,image=self.photoimage,compound=TOP, command= lambda : controller.show_frame(Page2),
activebackground= "green",background="red",foreground="white")
lang_btn['font'] = lang_btnFont
lang_btn.place(x=1010,y=60)
lang_btn2 = tk.Button(self,text="हिन्दी",height=300, width=300,image=self.photoimage,compound=TOP,
command= lambda : controller.show_frame(Page2), activebackground=
"green",background="red",foreground="white")
lang_btn2['font'] = lang_btnFont
lang_btn2.place(x=1010,y=400)
button1 = ttk.Button(self, text ="StartPage",image=self.photoimage,command= lambda :
controller.show_frame(StartPage))
button1.grid(row = 1, column = 1,padx = 10,pady = 10)
button2 = ttk.Button(self,text = "Page 2", command = lambda : controller.show_frame(Page2))
button2.grid(row = 2, column = 1,padx = 10,pady = 10)
self.timer_label1 = tk.Label(self,font = LARGEFONT, text="10s")
self.timer_label1.place(x=2,y=200)
self.timer_thread = Thread(target = self.on_show_frame)
self.timer_thread.start()
self.after(100,self.on_show_frame)
self.bind("<<ShowFrame>>", self.on_show_frame)
def on_show_frame(self,event=None):
print("page1 is shown..")
self.start = 10
self.temp = self.start
while self.temp >= 0:
self.timer_label1.config(text = str(self.temp)+ "s")
self.timer_label1.update()
if self.temp == 0:
self.timer_thread._is_running = False
show_frame_g(StartPage)
break
self.temp -=1
sleep(1)
class Page2(tk.Frame):
def __init__(self,parent,controller):
tk.Frame.__init__(self, parent)
label = ttk.Label(self,text = "Page 2", font = LARGEFONT)
label.grid(row = 0,column = 4,padx=10,pady = 10)
self.img1 = PIL.ImageTk.PhotoImage(file=r'C:\\Users\\mojave\\tkinter\\bg_image2.jpg')
displayCanvas1 = ttk.Label(self)
displayCanvas1.config(image=self.img1)
displayCanvas1.place(x=0,y=0)
button1 = ttk.Button(self, text = "Page 1",command = lambda : controller.show_frame(Page1))
button1.grid(row = 1,column = 1, padx = 10,pady = 10)
button2 = ttk.Button(self,text="Start Page", command = lambda : controller.show_frame(StartPage))
button2.grid(row = 2, column = 1,padx = 10, pady = 10)
self.bind("<<ShowFrame>>", self.on_show_frame)
def on_show_frame(self,event):
print("page2 is shown..")
#self.after(10000,lambda : show_frame_g(StartPage))
app = tkinterApp()
show_frame_g = app.show_frame
#def time_update():
# onTime_page2 =+ 1
def slideShow():
img = next(photos)
displayCanvas.config(image=img)
app.after(1000,slideShow) #after 1s
app.mainloop()
The problem is that the timer of other pages is running in background and randomly takes user to start page. I am not able to figure out how to solve this

my code was working fine until i changed something and now it wont run, whats wrong?

something was wrong with my code and i tried to fix it, now it doesn't run at all, no window pops up, when i stop the code, it says Process finished with exit code -1. i think i changed something from line 24, but not sure what happened. please tell me everything that's wrong with the code, and i believe theres a few that i cant find. thanks
from tkinter import *
import random
p = 0
x = random.randint(5, 12)
y = random.randint(5, 12)
class Starting:
def __init__(self, master):
self.master = master
self.frame = Frame(master, padx=200, pady=200)
self.frame.grid()
self.title = Label(self.frame, text="Multi-level Maths Quiz",
font=("Helvetica", "20", "bold"))
self.title.grid(row=0, padx=30, pady=30)
self.usern = Label(self.frame,text="Please enter a username", font=("16"))
self.usern.grid(row=1, padx=20, pady=20)
self.userentry = Entry(self.frame, width=50)
self.userentry.grid(row=2)
self.usercont = Button(self.frame, text="Continue", command=self.clear1)
self.usercont.grid(row=3)
def clear1(self):
self.frame.destroy()
ins1 = Questions(self.master)
class Questions:
while p < 5:
def __init__ (self, master):
self.user_choice = StringVar()
self.user_choice.set("")
self.frame = Frame(master, padx=200, pady=200)
self.frame.grid()
self.q = Label(self.frame, text="What is {} + {} ?".format(x, y))
self.q.grid(row=0)
self.ans = Entry(self.frame, width=50, textvariable=self.user_choice)
self.ans.grid(row=1)
self.answer = x+y
self.sub = Button(self.frame, text="submit", command=self.correct)
self.sub.grid(row=3)
def correct(self):
if int(self.user_choice.get()) == self.answer:
cor = Label(text="Correct!")
cor.grid(row=3, pady=50)
global p
p += 1
else:
inc = Label(text="incorrect")
inc.grid(row=3)
if __name__ == "__main__":
root = Tk()
root.title = ("Maths Quiz")
instance = Starting(root)
root.mainloop()
The line
while p < 5:
seems strange to me being in a class definition before the initialisation. This means if your p is >= 5 the class will never actually be defined as anything. This does not seem intended. If you comment it out and re-indent your def __init__() and def correct(self): functions the code seems to run again

creating button with tkinter

I was really curious why I cannot get my add_button to work,
as the window fails to come up when creating it.
from tkinter import *
class Calculator:
#-------------------------------------------------
def __init__(self, master):
self.master = master
master.title("Calculator")
self.close_button = Button(master, text = "Close", command = master.destroy)
Label(master, text = "First Digit").grid(row = 0)
Label(master, text = "Second Digit").grid(row = 1)
self.input1 = 0
self.input2 = 0
input1 = Entry(master)
input2 = Entry(master)
input1.grid(row = 0, column = 1)
input2.grid(row = 1, column = 1)
self.close_button.grid(row = 2, column = 0)
self.add_buton = Button(master, text = "Add", command = self.add())
self.add_button.grid(row = 2, column = 1)
master.configure(background = 'grey')
return
#-------------------------------------------------
def add(self):
return self.input1.get() + self.input2.get()
#-------------------------------------------------
#-------------------------------------------------
root = Tk()
calc = Calculator(root)
root.mainloop()
#-------------------------------------------------
Welcome to Stack!
I've looked through you code I've been able to do what you are asking. There were a few errors within your code:
a) you had self.add_buton and self.add_button which caused an error.
b) self.input1 = 0 and self.input2 = 0 are not required.
c) You were calling self.add() as the command and you should be calling self.add. When calling it as a command you do not need ()
d)input1 = Entry(master) should be self.input1 = tk.Entry(master)
e) You should convert your input values into int or float as otherwise it will just one value onto the end of the other. (Eg, 1 + 5 = 15 whereas int(1) + int(5) = 6
Here is your code with the entry boxes working as they should. I have import tkinter as tk hence why it is tk.Entry
from tkinter import *
import tkinter as tk
class Calculator:
#-------------------------------------------------
def __init__(self, master):
self.master = master
master.title("Calculator")
self.close_button = Button(master, text = "Close", command = master.destroy)
Label(master, text = "First Digit").grid(row = 0)
Label(master, text = "Second Digit").grid(row = 1)
self.input1 = tk.Entry(bd=5, width=35, background='gray35', foreground='snow')
self.input2 = tk.Entry(bd=5, width=35, background='gray35', foreground='snow')
self.input1.grid(row = 0, column = 1)
self.input2.grid(row = 1, column = 1)
self.close_button.grid(row = 2, column = 0)
self.add_button = tk.Button(master, text = "Add", command = self.add)
self.add_button.grid(row = 2, column = 1)
master.configure(background = 'grey')
return
#-------------------------------------------------
def add(self):
val = self.input1.get()
print(val)
#-------------------------------------------------
#-------------------------------------------------
root = Tk()
calc = Calculator(root)
root.mainloop()
This should now work how you wanted it too. The variables within the entry can be changed to suit. You were correct in calling the value of the entry with self.input1.get().
Hope this has helped.

Pass CheckButton's number using Python Class

I created a class in order to create a batch of checkbuttons as follows.
I'm trying to get the chekbutton's number to indicate which one was pressed( with no success ).
stat functio, when called, sends status of all checkbuttons.
any ideas ?
class dev_buttons2(object):
def __init__(self,master,buts_list):
self.status=[]
for i in range(len(buts_list)):
self.var = IntVar()
self.name=buts_list[i]
self.c = Checkbutton(master,text=buts_list[i], variable=self.var,
indicatoron=0,command=self.cb,width=10,height=2)
self.c.grid(column=i, padx=5,row = 10)
self.status.append(self.var)
def cb(self):
print(self.name)
def stat():
return self.status
Using Lambda function - I passed as much values as I want to arg ( see comment at code ).
class SwitchButtons:
def __init__(self, master, frame, num_of_buttons):
self.master = master
self.status = []
self.buts = []
self.leds = []
bg_window = "DeepSkyBlue4"
self.framein = Frame(frame)
self.framein.grid(padx=5, pady=5)
#Create Widgets of buttons
for i in range(num_of_buttons):
button_var = StringVar()
entry_var = IntVar()
led_var = StringVar()
t = 35
ent = Entry(self.framein, textvariable=entry_var, width=4, justify="center")
ent.grid(column=i, row=2, sticky=W, padx=t)
led = Label(self.framein, textvariable=led_var, width=4, bg="red", fg="white", relief="ridge")
led_var.set("off")
led.grid(row=0, column=i, pady=0)
c = Checkbutton(self.framein, text="Switch " + str(i), variable=button_var, indicatoron=0,
width=10, height=2, onvalue="on", offvalue="off",
command=lambda arg=[i, button_var, entry_var]: #### Use Lambda to pass several arguments to "arg"
self.cb(arg))
c.grid(column=i, padx=30, pady=5, row=1)
button_var.set("off")
mins = Label(self.framein, text="min.", width=4, justify="center", fg="black")
mins.grid(column=i, row=2, sticky=E, padx=t)
self.status.append([button_var, led_var, entry_var])
self.buts.append(c)
self.leds.append(led)
###
def cb(self, but, state='', a=''):
# but = [ switch#, switch state, delay] ## explanatory
##In use only in CB_DELAYED
if state != '':
but[1].set(state)
def switch_onoff():
if but[1].get() == "on":
self.leds[but[0]].config(bg="green")
self.status[but[0]][1].set("on")
elif but[1].get() == "off":
self.leds[but[0]].config(bg="red")
self.status[but[0]][1].set("off")
if but[2].get() > 0 and but[1].get() == "on":
a = ", Auto shutdown in %s minutes." % (but[2].get())
switch_onoff()
print("Delayed", but[1].get())
self.cb_delayed(but)
else:
switch_onoff()
self.master.loop.device_chage_state(but[0], but[1].get(), text=a)
def cb_delayed(self, but):
self.framein.after(but[2].get() * 1000, self.cb, but, "off")

Categories