Draw a GUI that overrides another GUI in Tkinter - python

I am writing a GUI with the screen of Raspberry.Each time I destroy a GUI and call a new GUI there will be a delay of about a few seconds to make the user see the raspberry's desktop. I want to draw a loading interface down to the background so that when I switch the screen the user won't see the raspberry desktop. I use this code:
from tkinter import *
class Load_Screen:
def __init__(self, master):
self.master = master
self.master.configure(background='white')
self.frame = Frame(self.master)
self.frame.pack()
self.canvas = Canvas(self.frame, width = 350, height = 250)
self.canvas.configure(background='white')
self.canvas.pack()
self.img = PhotoImage(file="image/loading.png")
self.canvas.create_image(55,150, anchor=W, image=self.img)
newWindow = Toplevel(self.master)
newWindow.geometry("700x500")
app = Main_Screen(newWindow)
class Main_Screen:
def __init__(self, master):
self.master = master
self.frame = Frame(self.master)
self.frame.pack()
def main():
root = Tk()
root.geometry("760x600")
app = Load_Screen(root)
root.mainloop()
if __name__ == '__main__':
main()
However, the loading screen overrides the main screen. And I want the opposite, the bottom loading screen and the main screen above

This is my solution which i have found at
How to make a Tkinter window jump to the front?
from tkinter import *
class Load_Screen:
def __init__(self, master):
self.master = master
self.master.configure(background='white')
self.frame = Frame(self.master)
self.frame.pack()
self.canvas = Canvas(self.frame, width = 350, height = 250)
self.canvas.configure(background='white')
self.canvas.pack()
self.img = PhotoImage(file="image/loading.png")
self.canvas.create_image(55,150, anchor=W, image=self.img)
newWindow = Toplevel(self.master)
newWindow.geometry("700x500")
app = Main_Screen(newWindow)
class Main_Screen:
def __init__(self, master):
self.master = master
self.frame = Frame(self.master)
self.frame.pack()
def main():
root = Tk()
root.geometry("760x600")
root.lift()
app = Load_Screen(root)
root.mainloop()
if __name__ == '__main__':
main()
Use root.lift() make Load_Screen below Main_Screen

Related

customtkinter - create frame with other class than the main frame but then assign it to the main frame

i am trying to create parts of my customtkinter-app in other classes so i can then assign them to the App class. But i must do something wrong. As you can see the goal is to place the labeltext from "self.label" to the middle of the frame "self.frame_rot"
Please check my code:
import tkinter
import customtkinter as ctk
class Frame1(ctk.CTkFrame):
def __init__(self, master):
super().__init__(master)
self.frame_rot = ctk.CTkFrame(master, height = 100, width = 100, fg_color = 'red').grid(row = 0, column = 0)
self.label = ctk.CTkLabel(self.frame_rot, text = 'hallo').place(relx = 0.5, rely = 0.5, anchor = 'center')
class App(ctk.CTk):
def __init__(self):
super().__init__()
self.geometry('500x500')
self.title('TestApp')
self.frame = Frame1(self)
if __name__ == "__main__":
app = App()
app.mainloop()
I just dont know what to do from here on!!
try this:
import tkinter
import customtkinter as ctk
class App(ctk.CTk):
def __init__(self):
super().__init__()
self.geometry('500x500')
self.title('TestApp')
self.frame = Frame1(self)
class Frame1(ctk.CTkFrame):
def __init__(self, master):
super().__init__(master)
#if you remove this, the "red block" will stick to the upper left corner
master.grid_columnconfigure(0, weight=1)
master.grid_rowconfigure(0, weight=1)
self.frame_rot = ctk.CTkFrame(master=master, fg_color='red')
self.frame_rot.grid(row=0, column=0)
#sticky "ns" will centralize the label vertically
self.label = ctk.CTkLabel(master=self.frame_rot, text='hallo', height=130)
self.label.grid(row=0, column=0, sticky="ns")
if __name__ == "__main__":
app = App()
app.mainloop()

Cannot use .place command for tkinter

I use .place command to indicate the place of "TEXT" (100, 70), but cannot reflect in the window even if changing it to any coordinate.
Could you specify the problem?
import tkinter as tk
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.pack()
self.create_widgets()
self.master.geometry("600x300")
def create_widgets(self):
self.msg1 = tk.Label(self, text = "TEXT")
self.msg1.place(x = 100, y = 70)
self.msg1.pack()
if __name__ == "__main__":
root = tk.Tk()
app = Application(master = root)
app.mainloop()
Few corrections to make:
Don't use .pack() geometry manager after .place geometry manager, or pack() will over ride .place() manager:
def create_widgets(self):
self.msg1 = tk.Label(self, text = "TEXT")
self.msg1.place(x = 100, y = 230)
Use fill and expand parameter to pack the Frame:
self.pack(fill=tk.BOTH,expand=1)
Here is the code:
import tkinter as tk
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.pack(fill=tk.BOTH,expand=1)
self.create_widgets()
self.master.geometry("600x300")
def create_widgets(self):
self.msg1 = tk.Label(self, text = "TEXT")
self.msg1.place(x = 100, y = 230)
if __name__ == "__main__":
root = tk.Tk()
app = Application(master = root)
app.mainloop()
Don't use both .pack() and .place(), use one of them instead.
Let's say to use .place():
import tkinter as tk
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.create_widgets()
self.place(relwidth = 1, relheight = 1)
self.master.geometry("600x300")
def create_widgets(self):
self.msg1 = tk.Label(self, text = "TEXT")
self.msg1.place(x = 100, y = 70)
if __name__ == "__main__":
root = tk.Tk()
app = Application(master = root)
app.mainloop()
I replaced self.pack() with self.place(relwidth = 1, relheight = 1), so the frame will be always wide as the window.
Then I deleted self.msg1.pack().
Now it should work.

Tkinter canvas not showing up

I'm quite new to Tkinter and this is my first program, can anyone tell me why the canvas is not showing up? I'm not getting any errors so I assume it is working but just not visible? I tried moving it up a layer but it was still invisible. Here is my code:
from Tkinter import *
import Tkinter as tk
class Application(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.frame = Frame(self.master)
self.master = master
self.window()
self.drawFigure()
# self.master.attributes('-fullscreen', True)
self.master.bind("<Escape>", self.end_fullscreen)
def window(self):
self.frame = Frame(self.master)
screen_width = self.frame.winfo_screenwidth() / 2
screen_height = self.frame.winfo_screenheight() / 2
self.master.geometry('%dx%d' % (screen_width, screen_height))
def end_fullscreen(self, event=None):
self.master.attributes("-fullscreen", False)
def drawFigure(self):
self.frame = Frame(self.master)
self.C = Canvas(self.frame, width=200, height=200, bg = 'red')
self.C.pack()
self.C.create_rectangle(50, 20, 150, 80, fill="#476042")
if __name__ == '__main__':
root = tk.Tk()
w = Application(root)
w.master.mainloop()
Appreciate all the input.
You import Tkinter and Tkinter as tk, which gets confusing.
Application inherits from Frame so you don't have to create additional frames inside. Certainly not more than one named self.frame.
How about this:
from Tkinter import *
class Application(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.master = master
self.pack()
self.window()
self.drawFigure()
self.master.bind("<Escape>", self.end_fullscreen)
def window(self):
screen_width = self.winfo_screenwidth() / 2
screen_height = self.winfo_screenheight() / 2
self.master.geometry('%dx%d' % (screen_width, screen_height))
def end_fullscreen(self, event=None):
self.master.attributes("-fullscreen", False)
def drawFigure(self):
self.C = Canvas(self, width=200, height=200, bg = 'red')
self.C.pack()
self.C.create_rectangle(50, 20, 150, 80, fill="#476042")
if __name__ == '__main__':
root = Tk()
w = Application(root)
w.master.mainloop()
You forgot to call pack() on the Frame you created in drawFigure():
def drawFigure(self):
self.frame = Frame(self.master)
self.frame.pack() # <--- There
self.C = Canvas(self.frame, width=200, height=200, bg = 'red')
self.C.pack()
self.C.create_rectangle(50, 20, 150, 80, fill="#476042")
You’re creating three sub frames of your parent, storing each of them as self.frame (so all but the last one are lost), and not placing any of them anywhere.
So, you’ve correctly placed the canvas on one of these invisible frames, but that doesn’t do any good.
I’m not sure what you’re trying to do with all these separate frames.
If you really need three sibling frames, you have to store them in separate variables, or in a list, or something, and you need to place them.
If you need one sibling frame, just create it once instead of three times, and again, you need to place it.
If you need three or one child frames instead of sibling frames, create them with self rather than self.master.
If you don’t need any sibling or child frames at all, don’t create them, and just place the canvas on self instead of self.frame.

Tkinter - Hide and show main screen from toplevel

I am trying to create a main screen that is displayed only if the login is successful, but i cant figure out how to make the main screen visible/invisible
from tkinter import *
class Login_screen(Frame):
def __init__(self,master):
self.open_login()
def open_login(self):
self.root2 = Toplevel()
self.root2.geometry("400x200")
self.grid_forget()
self.app2 = Main_screen(self.root2)
class Main_screen(Frame):
def __init__(self,master):
Frame.__init__(self,master)
self.master.grid()
self.button = Button(master = self,text = "Close",command = lambda: self.close_windows())
self.button.grid()
def close_windows(self):
self.master.destroy()
Login_screen.master.grid()
root = Tk()
root.geometry("800x600")
app = Login_screen(root)
root.mainloop()
I figured out how it works:
from tkinter import *
class Main_screen(Frame):
def __init__(self,master):
Frame.__init__(self, master)
self.grid()
self.text = Label(text="Janela")
self.text.grid()
root.withdraw()
self.create_login()
def create_login(self):
self.root2 = Toplevel()
self.app2 = Login_screen(self.root2)
class Login_screen(Frame):
def __init__(self,master):
Frame.__init__(self,master)
self.grid()
self.botao1 = Button(self,text="Appear",command = lambda: self.show_main())
self.botao1.grid()
def show_main(self):
self.master.destroy()
root.deiconify()
root = Tk()
app = Main_screen(root)
root.mainloop()

Is it possible to keep the same window for every class in python's tkinter?

I am trying to create a program in tkinter which allows me to open an initial window then to keep it throughout all classes used. For example, if I was to create a button in a window then when I click this button, it would exuecute a method that destroys the widget, and then executes a new class that builds a new screen within the same window, such as text opposed to a button.
from tkinter import *
class Window1:
def __init__(self, master):
self.master = master
self.label = Button(self.master, text = "Example", command = self.load_new)
self.label.pack()
def load_new(self):
self.label.destroy()
## Code to execute next class
class Window2:
def __init__(self, master):
self.master = master
self.label = Label(self.master, text = "Example")
self.label.pack()
def main():
root = Tk()
run = Window1(root)
root.mainloop()
if __name__ == '__main__':
main()
I understand this is less practical, but I am curious. Cheers.
Tk() creates main window and variable root gives you access to this window. You can use root as argument for Window2 and you will have access to main window inside Window2
from tkinter import *
class Window1:
def __init__(self, master):
# keep `root` in `self.master`
self.master = master
self.label = Button(self.master, text="Example", command=self.load_new)
self.label.pack()
def load_new(self):
self.label.destroy()
# use `root` with another class
self.another = Window2(self.master)
class Window2:
def __init__(self, master):
# keep `root` in `self.master`
self.master = master
self.label = Label(self.master, text="Example")
self.label.pack()
root = Tk()
run = Window1(root)
root.mainloop()
--
Probably nobody use another class to create Label in place of Button ;)
--
EDIT: In this example using names Window1 and Windows2 is misleading because there is only one window and two classes which use this window. I would rather use names FirstOwner, SecondOwner
Everything is implemented in one Tk class and in this case there always is only one window.
from tkinter import *
from tkinter import ttk
class MainWindow():
def __init__(self, mainWidget):
self.main_frame = ttk.Frame(mainWidget, width=300, height=150, padding=(0, 0, 0, 0))
self.main_frame.grid(row=0, column=0)
self.some_kind_of_controler = 0
self.main_gui()
def main_gui(self):
root.title('My Window')
self.main_label_1 = ttk.Label(self.main_frame, text='Object_1')
self.main_label_1.grid(row=0, column=0)
self.main_label_2 = ttk.Label(self.main_frame, text='Object_2')
self.main_label_2.grid(row=1, column=0)
self.main_label_3 = ttk.Label(self.main_frame, text='Object_3')
self.main_label_3.grid(row=2, column=0)
self.setings_button = ttk.Button(self.main_frame, text='Setings')
self.setings_button.grid(row=0, column=1)
self.setings_button.bind('<Button-1>', self.setings_gui)
self.gui_elements = [self.main_label_1,
self.main_label_2,
self.main_label_3,
self.setings_button]
def setings_gui(self, event):
self.gui_elements_remove(self.gui_elements)
root.title('Setings')
self.main_label_1 = ttk.Label(self.main_frame, text='Object_1')
self.main_label_1.grid(row=2, column=0)
self.main_menu_button = ttk.Button(self.main_frame, text='Main menu')
self.main_menu_button.grid(row=0, column=1)
self.main_menu_button.bind('<Button-1>', self.back_to_main)
self.some_kind_of_controler = 1
self.gui_elements = [self.main_label_1,
self.main_menu_button]
def back_to_main(self, event):
if self.some_kind_of_controler == 1:
self.gui_elements_remove(self.gui_elements)
else:
pass
self.main_gui()
def gui_elements_remove(self, elements):
for element in elements:
element.destroy()
def main():
global root
root = Tk()
root.geometry('300x150+50+50')
window = MainWindow(root)
root.mainloop()
if __name__ == '__main__':
main()

Categories