Tkinter Python classes and variables - python-3.x

I tried to create a multi-frame python application. However, when I try to retrieve the information from the radiobutton, python throws me an error saying the variable "movie " is not defined. Can someone explaining me what am I missing?
To my understanding, I guess the problem is that the variable is declared inside the class. I tried to make the variable global, but it did not help in solving the problem.
import tkinter as tk
from tkinter import *
from tkinter import ttk
LARGE_FONT=("Verdana", 12)
class Movies(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self,*args, **kwargs)
tk.Tk.wm_title(self, "Movie I like")
tk.Tk.wm_geometry(self, "500x500")
container=tk.Frame(self)
container.pack(side="top", fill="both", expand="True")
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)
def show_frame(self, cont):
frame=self.frames[cont]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
s = ttk.Style()
s.configure('my.TButton', font=('Verdana', 8))
label=tk.Label(self, text="Home Page", font=LARGE_FONT)
label.pack(pady=10, padx=30)
button_load=ttk.Button(self, text="Kind of Movie ", width=30, style='my.TButton',
command= lambda: controller.show_frame(PageOne))
button_load.pack(padx=30)
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
movie= tk.StringVar()
movie.set("1")
mybutton=ttk.Radiobutton(self, text='Drama', variable=movie, value="Drama").grid(column=1,row=1, sticky=W, padx=10)
mybutton1=ttk.Radiobutton(self, text='Comedy', variable=movie, value="Comedy").grid(column=2,row=1, sticky=W, padx=10)
button_submit=ttk.Button(self, text="Submit", width=15,
command=save_info).grid(column=3, row= 10, padx=5)
def save_info():
movie_info=movie.get()
print("you like " + movie_info)
app=Movies()
app.mainloop()

Related

(most likely due to a circular import) how to switch between multiple pages in tkinter?

i've been trying to create a little app for navigate between three pages using tkinter, all the pages are written in different python files, the scripts are bellow.
First file for start page:
import tkinter as tk
from tkinter import ttk
import first_window as fw
import second_window as sw
class Library_Management_System(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
#create a frame who's contain the frames
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.frames = {} #create a dictionaries for frames
for f in (StartPage, fw.first, sw.second):
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()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
tk.Frame.configure(self, bg='red')
first_button = ttk.Button(self, text='Page One',
command = lambda : controller.show_frame(fw.PageOne)).pack()
second_button = ttk.Button(self, text='Page two',
command = lambda : controller.show_frame(sw.second_window)).pack()
app = Library_Management_System()
app.geometry('200x200+200+200')
app.mainloop()
Second file for first page:
import tkinter as tk
from tkinter import ttk
import main as m
import second_window as sw
class first(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
tk.Frame.configure(self,bg='red')
second_button = ttk.Button(self, text='Page Two',
command=lambda : controller.show_frame(sw.second_window)).pack()
start_button = ttk.Button(self, text='Start Page',
command=lambda : controller.show_frame(m.StartPage)).pack()
Third file for second page:
import tkinter as tk
from tkinter import ttk
import main as m
import first_window as fw
class second(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
tk.Frame.configure(self, bg='green')
start_button = ttk.Button(self, text='Start Page',
command=lambda : controller.show_frame(m.StartPage)).pack()
first_button = ttk.Button(self, text='Page One',
command=lambda : controller.show_frame(fw.first_window)).pack()
i get this error:
for f in (StartPage, fw.first, sw.second):
AttributeError: partially initialized module 'first_window' has no attribute 'first' (most likely due to a circular import)
why it doesn't recognize the module first.

I want to make a GUI but i get this error: self.frame.grid(row=0, column=0, sticky="nsew") AttributeError: 'function' object has no attribute 'grid'

Sorry about the layout of this question, my first time working with stackoverflow posts.
I want to make a GUI for Tic Tac Toe (Game menu). And have the abillity to put buttons where ever i want in the GUI so i used Grid.
import tkinter as tk
LARGE_FONT= ("Verdana", 12)
class SeaofBTCapp(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.frames = {}
for F in (MainWindow, Game, Difficulty):
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()
class MainWindow(tk.Tk):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Welcom to TIC TAC TOE", font=LARGE_FONT)
label.pack(pady=10, padx=10)
button1 = tk.Button(self, text="Start",
command=lambda: controller.show_frame(Game))
button1.pack()
button2 = tk.Button(self, text="Diffeculty",
command=lambda: controller.show_frame(Difficulty))
button2.pack()
button3 = tk.Button(self, text="Quit", command=self.Quit)
button3.pack()
label1 = tk.Label(self, text="Made by VindictaOG")
label1.pack()
def Quit(self):
exit()
class Game(tk.Tk):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
button1 = tk.Button(self, text="New Game")
button1.pack()
button2= tk.Button(self, text="Back to homescreen",
command=lambda: controller.show_frame(MainWindow))
button2.pack()
class Difficulty(tk.Tk):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
button1 = tk.Button(self, text="1V1", command=lambda: controller.show_frame(MainWindow))
button1.pack()
button2 = tk.Button(self, text="Back to homescreen",
command=lambda: controller.show_frame(Game))
button2.pack()
gui = SeaofBTCapp()
gui.mainloop()
But when i use grid i get this error:
Traceback (most recent call last):
File "/home/ivar/PycharmProjects/J1B2Afvink6/BKE.py", line 82, in <module>
gui = SeaofBTCapp()
File "/home/ivar/PycharmProjects/J1B2Afvink6/BKE.py", line 27, in __init__
frame.grid(row=0, column=0, sticky="nsew")
TypeError: wm_grid() got an unexpected keyword argument 'row'
I tried it with pack but that would not work, does someone know how to fix this?
Should inherit from tk.Frame instead of tk.Tk for MainWindow, Game and Difficulty. Also StartPage is not defined. #acw1668
Using (tk.Frame, tk.Tk) instead of just (tk.Tk) solved the problem.

_tkinter.TclError: unknown option "-menu"

I am trying to write the object-oriented code in Python. Now I am stuck with an error:
_tkinter.TclError: unknown option "-menu"
I think the error lies in following line:
self.config(menu=menubar)
Following is my code:
import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
import time
LARGE_FONT = ("Verdana", 12)
class ImgComp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self,width=320, height=209)
container.pack(side="top")
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
container.grid_propagate(False)
self.frames = {}
for F in (PageOne):
frame = F(container, self)
#frame['bg'] = 'red'
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(PageOne)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
menubar = tk.Menu(self)
filemenu = tk.Menu(menubar, tearoff=0)
filemenu.add_command(label="New")
filemenu.add_command(label="Open")
menubar.add_cascade(label="Settings", menu=filemenu)
self.config(menu=menubar)
label = tk.Label(self, text="Page One", font=LARGE_FONT)
label.pack(pady=10,padx=10)
app = ImgComp()
app.mainloop()
Also I would like to inform, I have truncated the code as I was not allowed to post a bigger code by stackoverflow. Please help.

How to open and close another window with scrollbar in tkinter for python 3.5.?

I want to build a Tkinter app in python 3.5. with a StartPage and a another window PageTwo that includes a table with a scolldownbar. I have tried to apply a framework from an online tutorial and the listbox example from another website.
My problem is: when I run the program both pages are loaded directly. How can I manage to let PageTwo only open on click on Button in StartPage, and then apply another button in PageTwo that closed PageTwo again and redirects to StartPage?
Second question: Alternatively to the listbox example I would like to use canvas with scrollbar on PageTwo. But how and where do I have to introduce the canvas? I get totally messed up with all the inheritances throughout the different classes.
If you would suggest a complete different setup, this would also be fine.
Many thanks for your help.
import tkinter as tk
class GUI(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.frames = {}
for F in (StartPage, PageTwo):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
frame = StartPage(container, self)
self.frames[StartPage] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise() # zeigt Frame oben an
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Your choice?")
label.pack(pady=10,padx=10)
button1 = tk.Button(self, text="Open PageTwo",
width = 25, command=lambda: controller.show_frame(PageTwo))
button1.pack(pady=10, padx=10)
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
master = tk.Tk()
scrollbar = tk.Scrollbar(master)
scrollbar.pack(side=tk.RIGHT, fill="y")
listbox = tk.Listbox(master, yscrollcommand=scrollbar.set)
for i in range(1000):
listbox.insert(tk.END, str(i))
listbox.pack(side=tk.LEFT, fill="both")
scrollbar.config(command=listbox.yview)
if __name__ == '__main__':
app = GUI()
app.mainloop()
To fix the issues:
initialize PageTwo only when the button is clicked
use Toplevel for popup window
use root as the StartPage
Below is a demo based on your posted code:
import tkinter as tk
from tkinter import ttk
class GUI(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)
label = tk.Label(self, text="Your choice?")
label.pack(pady=10,padx=10)
button1 = ttk.Button(self, text="Open PageTwo", width=25, command=lambda: self.show_frame(PageTwo))
button1.pack(pady=10, padx=10)
button2 = ttk.Button(self, text="Open PageCanvas", width=25, command=lambda: self.show_frame(PageCanvas))
button2.pack(pady=10, padx=10)
def show_frame(self, page):
win = page(self)
# make window modal
win.grab_set()
self.wait_window(win)
class PageTwo(tk.Toplevel):
def __init__(self, parent):
tk.Toplevel.__init__(self, parent)
self.title('Two')
scrollbar = tk.Scrollbar(self)
scrollbar.pack(side=tk.RIGHT, fill="y")
listbox = tk.Listbox(self, yscrollcommand=scrollbar.set)
for i in range(1000):
listbox.insert(tk.END, str(i))
listbox.pack(side=tk.LEFT, fill="both")
scrollbar.config(command=listbox.yview)
class PageCanvas(tk.Toplevel):
def __init__(self, parent):
tk.Toplevel.__init__(self, parent)
self.title('Canvas')
self.geometry('400x600')
canvas = tk.Canvas(self, bg='white', scrollregion=(0, 0, 400, 20000))
canvas.pack(fill='both', expand=True)
vbar = tk.Scrollbar(canvas, orient='vertical')
vbar.pack(side='right', fill='y')
vbar.config(command=canvas.yview)
canvas.config(yscrollcommand=vbar.set)
for i in range(1000):
canvas.create_text(5, i*15, anchor='nw', text=str(i))
if __name__ == '__main__':
app = GUI()
app.mainloop()

module 'tkinter' has no attribute 'Tk' with python 3.5

Launching my program i visualized this error: "module 'tkinter' has no attribute 'Tk'". So I changed the name of my program from "tkinter.py" to "tkinterrr.py" but I obtain that error as well. What can I do?
That's the code:
import tkinter as tk
LARGE_FONT = ("Verdana", 12)
class SeaofBTCapp(tk.Tk):
def __init__(self, *args, **kwargs): #args all var, kwargs all dict
tk.Tk.__init__(self, *args, **kwargs)
container = Tk.Frame(self) #frame hedge window
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
frame = StartPage(container, self)
self.frames[StartPage] = frame
frame.grid(row=0, column=0, sticky="nsew") #you specify all grid
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont] # key
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Start Page", font=LARGE_FONT) #Label class label object
label.pack(pady=10, padx=10)
app = SeaofBTCapp()
app.mainloop()
Ok I solved... I didn't delete the old "tkinter.py" file from the directory!

Categories

Resources