The following is an excerpt of a my first python project I am currently working on.
I am able to add the check button into the GUI, but it is practically useless because I can't find out how I can get the value from the checkbutton.
import tkinter as tk
from tkinter import *
class base(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
#tk.Tk.iconbitmap(self, "iconz.ico")
tk.Tk.wm_title(self, "Mandelbrot Renderer")
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, MainPage):
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 MainPage(tk.Frame):
def getcheckvalue(self):
print (self.mvar.get())
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Graph Page!", font=LARGE_FONT)
label.pack(pady=10,padx=10)
button1 = ttk.Button(self, text="Back to Home",
command=lambda: controller.show_frame(StartPage))
button1.pack()
button2 = ttk.Button(self, text="Re-Render",
command=self.getcheckvalue)
button2.pack()
mvar = IntVar()
self.cbutton = ttk.Checkbutton(self, text="shadow",onvalue=1, offvalue=0, variable=mvar)
self.cbutton.pack()
app = base()
app.geometry ("800x600")
app.mainloop()
mvar = IntVar()
In this line you are creating a local mvar. To access it from outside of your __init__ method, you need to make it class variable by adding self. prefix.
self.mvar = IntVar()
self.cbutton = ttk.Checkbutton(..., variable=self.mvar)
Related
I use following code:
Switch between two frames in tkinter
import tkinter as tk # python 3
from tkinter import font as tkfont # python 3
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic")
# the container is where we'll stack a bunch of frames
# on top of each other, then the one we want visible
# will be raised above the others
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, PageOne):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
# put all of the pages in the same location;
# the one on the top of the stacking order
# will be the one that is visible.
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame("StartPage")
def show_frame(self, page_name):
'''Show a frame for the given page name'''
frame = self.frames[page_name]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="This is the start page", font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
self.giris = tk.Entry(self)
self.giris.pack()
self.yazi = tk.Label(self, text="Buraya GİRİLEN VERİ gelecek.")
self.yazi.pack()
button2 = tk.Button(self, text="ae",
command=lambda: [self.alinanmetin(), controller.show_frame("PageOne")])
button2.pack()
def alinanmetin(self):
il = self.giris.get()
self.yazi.config(text="Girdiğiniz il: %s" % il)
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="This is page 1", font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
button = tk.Button(self, text="Go to the start page",
command=lambda: controller.show_frame("StartPage"))
button.pack()
if __name__ == "__main__":
app = SampleApp()
app.geometry("600x400")
app.mainloop()
I want to change my frame according to the value I get from the entry.
if(il =="ali") i want change my frame and
if( il != "ali") i dont want do anything.
I am currently running two functions at the same time.How can i change frame after check value.
I need to update listbox when I'm changing view, but I dont know how to do it. On first page I'm adding some items to list and on second it should to show all items in listbox.
# -*- coding: utf-8 -*-
from tkinter import *
tb1 = [["Kofola", "0,5","30"]]
class SeaofBTCapp(Tk):
def __init__(self, *args, **kwargs):
Tk.__init__(self, *args, **kwargs)
container = 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, 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(Frame):
def __init__(self, parent, controller):
Frame.__init__(self,parent)
label = Label(self, text="Start Page")
label.pack(pady=10,padx=10)
button = Button(self, text="Visit Page 1",
command=lambda: controller.show_frame(PageOne))
button.pack()
button2 = Button(self, text="add",
command=self.add)
button2.pack()
def add(self):
tb1.append(["Radegast", "0,5","30"])
print(tb1)
class PageOne(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent)
label = Label(self, text="Page One!!!")
label.pack(pady=10,padx=10)
button1 = Button(self, text="Back to Home",
command=lambda: controller.show_frame(StartPage))
button1.pack()
self.bill=Listbox(self)
self.bill.pack()
for item in tb1:
co=" ".join(str(x) for x in item)
self.bill.insert(END, co)
app = SeaofBTCapp()
app.mainloop()
In the PageOne class You are reading the list tb1 only once, in __init__(). To get the changes in tb1 to be seen in the listbox you also have to update the listbox with the new altered list.
There is also an issue with the list. As it's defined in the global namespace your app will depend on this. I'd suggest you define it in the SeaofBTCapp() __init__() function and then you can access it through the controller object:
class SeaofBTCapp(Tk):
def __init__(self, *args, **kwargs):
Tk.__init__(self, *args, **kwargs)
self.tb1 = [["Kofola", "0,5","30"]]
... etc ...
class StartPage(Frame):
def __init__(self, parent, controller):
self.controller = controller
... etc ...
def add(self):
self.controller.tb1.append(["Radegast", "0,5","30"])
... etc ...
And then add an update() method to the PageOne() class which updates the listbox and calls it from the add() method. I'm calling by way of controller method update_pageone(). See full example below:
from tkinter import *
class SeaofBTCapp(Tk):
def __init__(self, *args, **kwargs):
Tk.__init__(self, *args, **kwargs)
self.tb1 = [["Kofola", "0,5","30"]] # Create instance variable tb1
container = 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, 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()
def update_pageone(self):
self.frames[PageOne].update() # Call update on PageOne
class StartPage(Frame):
def __init__(self, parent, controller):
self.controller = controller # Remember the controller
Frame.__init__(self,parent)
label = Label(self, text="Start Page")
label.pack(pady=10,padx=10)
button = Button(self, text="Visit Page 1",
command=lambda: self.controller.show_frame(PageOne))
button.pack()
button2 = Button(self, text="add", command=self.add)
button2.pack()
def add(self):
self.controller.tb1.append(["Radegast", "0,5","30"])
self.controller.update_pageone() # Asking controller for an update
class PageOne(Frame):
def __init__(self, parent, controller):
self.controller = controller # Remember the controller
Frame.__init__(self, parent)
label = Label(self, text="Page One!!!")
label.pack(pady=10,padx=10)
button1 = Button(self, text="Back to Home",
command=lambda: controller.show_frame(StartPage))
button1.pack()
self.bill = Listbox(self)
self.bill.pack()
for item in controller.tb1:
co = " ".join(str(x) for x in item)
self.bill.insert(END, co)
def update(self):
# Delete all from Listbox bill
self.bill.delete(0, 'end')
# Add revised table into Listbox bill
for item in self.controller.tb1:
co = " ".join(str(x) for x in item)
self.bill.insert(END, co)
app = SeaofBTCapp()
app.mainloop()
I am trying to make a tkinter widow with multiple frames, but also the functions of notebook, like multiple widows. The problem is I am kind of unfamiliar with tkinter and am not sure how to do that. This is my current code, and it doesn't work, and would love to know what I should do to make it work. Again, the dream end result would be that I would have a first widow, which says the test text, and then the 2nd window which has multiple tabs.
from tkinter import ttk
import tkinter as tk
Font= ("Verdana", 8)
LargeFont = ("Verdana", 12)
class App(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, 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)
label = tk.Label(self, text="Info", font=LargeFont)
label.pack(pady=2,padx=10)
text = tk.Label(self, text="testtestestetetqwegfegeg\ntestwegwegwegweg", font=Font)
text.pack(pady=2,padx=2)
button = tk.Button(self, text="Go to the Card",
command=lambda: controller.show_frame(PageOne))
button.pack(fill="x")
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
nb = ttk.Notebook(ttk.Frame())
nb.grid(row=1, column=0, columnspan = 50, rowspan=49, sticky='nesw')
p1 = (nb)
nb.add(p1, text='test')
label = tk.Label(self, text="", font=LargeFont)
label.pack(pady=10,padx=10)
button1 = tk.Button(self, text="Back to Home",
command=lambda: controller.show_frame(StartPage))
button1.pack()
app = App()
app.mainloop()
The error that I eventually get is that it creates a third frame that is displayed with the test tab. Everything else works.
Thanks for your help
I know exactly what you mean because I'm trying the same. To me
nb = ttk.Notebook(self)
worked.
best
Pkanda
Taubate Brazil
So I have read a few posts on here and have tried them all. The current method I have attempted is storing the data in the controller:
class App(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.app_data = {"building": tk.StringVar()}
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, PageOne,PageTwo):
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()
I then have my PageOne receive input from user as to what building they want:
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
#buidling
bldg_label = ttk.Label(self, text="Building Name (ie. ACAD):", font=LARGE_FONT)
bldg_label.grid(row=0, column=0, padx=2, pady = 10)
self.bldg_entry =ttk.Entry(self,width = 6, textvariable = self.controller.app_data["building"])
self.bldg_entry.grid(row=0, column=1, padx=2, pady=10)
button1 = ttk.Button(self, text="next", command = lambda: controller.show_frame(PageTwo))
button1.grid(row = 1, column = 0)
Lastly I want to display the building they typed into the entry box into a label like so:
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
bldg = self.controller.app_data["building"].get()
bldg_label = ttk.Label(self, text = "Building: " + str(bldg), font=LARGE_FONT)
bldg_label.grid(row = 0, column =0)
button1 = ttk.Button(self, text="Back to Home",
command=lambda: controller.show_frame(StartPage))
button1.grid(row = 1, column =0)
I know there needs to be some sort of updating but I just can't seem to get the right structure to make this work. The label prints: Building: with nothing in it. My question is how can I get the data that is stored in the dictionary to update the building label in the SecondPage? Any help would be greatly appreciated!
I'm making a multiwindow GUI in tkinter and I want to change the backgroundcolor of the gui. I've tried multiple suggested solutions and they don't work. For example root.configure(background='red'). This doesn't work either: http://www.java2s.com/Code/Python/GUI-Tk/SetFramebackgroundcolor.htm
import tkinter as tk
from tkinter import *
from tkinter import ttk
LARGE_FONT = ("Verdana", 12)
def loadmsg(msg):
popupload.fileName = filedialog.askopenfilename(filetypes=(("textfiler", ".txt"), ("Alla filer", ".*")))
class Dod(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.wm_title(self, "GUi")
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, 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):
ttk.Frame.__init__(self, parent)
label = ttk.Label(self, text="GUI", font=LARGE_FONT)
label.pack(pady=10, padx=10)
button = ttk.Button(self, text="Visit Page One",
command=lambda: controller.show_frame(PageOne))
button2 = ttk.Button(self, text="Ok",
command=lambda: controller.label2)
button.pack()
button2.pack()
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = ttk.Label(self, text="Page One", font=LARGE_FONT)
label.pack(pady=10, padx=10)
button1 = ttk.Button(self, text="Back to Home",
command=lambda: controller.show_frame(StartPage))
button1.pack()
root = Dod()
root.geometry("800x400")
root.mainloop()
This is very easy...
All you need to do is add a container.config() argument in the init function of the class Dod(tk.Tk) after the argument container.grid_columnconfigure(0, weight=1). Then, add frame.config(bg="black") after self.frames[F]=frame inside the loop for F in (start1,start,P1,P2).[This will give black colour to all frames in the loop]
The code is as follows:
import tkinter as tk
from tkinter import *
from tkinter import ttk
LARGE_FONT = ("Verdana", 12)
def loadmsg(msg):
popupload.fileName = filedialog.askopenfilename(filetypes=(("textfiler", ".txt"), ("Alla filer", ".*")))
class Dod(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.wm_title(self, "GUi")
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
F1.config()
self.frames = {}
for F in (StartPage, PageOne):
frame = F(container, self)
self.frames[F] = frame
frame.config(bg="black")
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):
ttk.Frame.__init__(self, parent)
label = ttk.Label(self, text="GUI", font=LARGE_FONT)
label.pack(pady=10, padx=10)
button = ttk.Button(self, text="Visit Page One",
command=lambda: controller.show_frame(PageOne))
button2 = ttk.Button(self, text="Ok",
command=lambda: controller.label2)
button.pack()
button2.pack()
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = ttk.Label(self, text="Page One", font=LARGE_FONT)
label.pack(pady=10, padx=10)
button1 = ttk.Button(self, text="Back to Home",
command=lambda: controller.show_frame(StartPage))
button1.pack()
root = Dod()
root.geometry("800x400")
root.mainloop()