_tkinter.TclError: unknown option "-menu" - python-3.x

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.

Related

Tkinter Python classes and variables

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()

Change Background Tkinter in Classes

I'm relatively new to Tkinter and Python and just started with Tkinter in object oriented way.
Im trying to change the background colour of all the different pages I have so i have the following code
import tkinter as tk
import sqlite3
from tkinter.ttk import *
from tkinter import *
LARGE_FONT = ("Verdana", 12)
HEIGHT = 700
WIDTH = 800
class programStart(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, minsize=WIDTH)
container.grid_columnconfigure(0, weight=1, minsize=HEIGHT)
self.frames = {}
for F in (StartPage, Register, LoginPage):
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() #Raises to front
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
I have tried container.configure(bg='red') and so on, to no success
How can I go about this issue?
Try this:
import tkinter as tk
import sqlite3
from tkinter.ttk import *
from tkinter import *
LARGE_FONT = ("Verdana", 12)
HEIGHT = 700
WIDTH = 800
class programStart(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, minsize=WIDTH)
container.grid_columnconfigure(0, weight=1, minsize=HEIGHT) #0 minimum, weight is priority
self.frames = {}
for F in (StartPage, Register, LoginPage):
frame = F(container, self, bg="red")
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() #Raises to front
class StartPage(tk.Frame):
def __init__(self, parent, controller, bg=None, fg=None):
tk.Frame.__init__(self, parent, bg=bg=, fg=fg)
# Make sure that all of the tkinter widgets have `bg=bg=, fg=fg`
Basically you need to tell all of the widgets that you are creating that the background should be red. When creating your widgets you can pass in the bg parameter (background).
This is a minimal version of the system I use to give the user of the GUI the ability to change the colors and fonts of all the widgets in the app according to color schemes he can choose himself.
import tkinter as tk
formats = {
'bg' : 'black',
'fg' : 'white'
}
class Labelx(tk.Label):
def __init__(self, master, *args, **kwargs):
tk.Label.__init__(self, master, *args, **kwargs)
def winfo_subclass(self):
''' a method that works like built-in tkinter method
w.winfo_class() except it gets subclass names
of widget classes custom-made by inheritance '''
subclass = type(self).__name__
return subclass
class Label(Labelx):
'''
If this subclass is detected it will be reconfigured
according to user preferences.
'''
def __init__(self, master, *args, **kwargs):
Labelx.__init__(self, master, *args, **kwargs)
self.config(
bg=formats['bg'],
fg=formats['fg'])
class LabelNegative(Labelx):
'''
If this subclass is detected it will be reconfigured
according to user preferences.
'''
def __init__(self, master, *args, **kwargs):
Labelx.__init__(self, master, *args, **kwargs)
self.config(
bg=formats['fg'],
fg=formats['bg'])
def change_colors():
for widg in (lab1, lab2):
if widg.winfo_class() == 'Label':
if widg.winfo_subclass() == 'Label':
widg.config(bg=formats['fg'], fg=formats['bg'])
elif widg.winfo_subclass() == 'LabelNegative':
widg.config(bg=formats['bg'], fg=formats['fg'])
root = tk.Tk()
f1 = tk.Frame(root)
f1.grid(column=0, row=0)
lab1 = Label(f1, text='Label')
lab1.grid()
lab2 = LabelNegative(f1, text='LabelNegative')
lab2.grid()
button = tk.Button(root, text='colorize', command=change_colors)
button.grid()
root.mainloop()

(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.

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!

Resources