change the position of already packed widget in tkinter - python-3.x

Here is the code,
from tkinter import *
root = Tk()
update_button = Button(root, text='Update')
update_button.pack()
def button():
frame1 = Frame(root)
frame1.pack()
button1 = Button(frame1, text="Button 1")
button1.pack(side=LEFT)
button2 = Button(frame1, text="Button 2")
button2.pack(side=LEFT)
button()
root.mainloop()
I want button1 to be stacked upon button2 when I click update button.
Help please.

Related

Make multiple tk.Toplevel windows embedded/unified in main tk window

So I'm trying to create a program which uses multiple tk.Toplevel windows. The problem with this is, that all windows show up seperated as their "own App", so when you alt tab, you switch between the toplevel windows.
The pseudocode would look something like this:
import tkinter as tk
top_levels = {}
def open_toplevel():
top_level = tk.Toplevel(root)
top_level.geometry("300x200+0+0")
top_levels.update({f"toplevel{len(top_levels.keys())}" : top_level})
root = tk.Tk()
button = tk.Button(root, command= open_toplevel)
button.place(x=0, y=0)
root.mainloop()
So my question, is: is there a way to unify them into "one window"?
If you want all of them to unify into one window then tk.Frame is a better widget to use instead of tk.Toplevel
The purpose of tk.Toplevel is to create a new temporary window, not an extra part of the window. But frames are a really good way to organise stuff.
This code below creates new frame every time you click the button. This is just a simple example. You can also use grid for widgets in a frame. I also put a border so you can see where the frames are located.
from tkinter import *
def open_frame():
frame = Frame(root, highlightbackground="black", highlightthickness=2)
lbl1 = Label(frame, text=f"Frame {len(frames) + 1} label 1")
lbl2 = Label(frame, text=f"Frame {len(frames) + 1} label 2")
lbl1.pack()
lbl2.pack()
frame.pack(padx=5, pady=5)
frames.append(frame)
root = Tk()
frames = []
btn = Button(root, text="Open Frame", command=open_frame)
btn.pack()
root.mainloop()
I hope this solution is helpful
EDIT
Use this code here to move the frames:
from tkinter import *
def open_frame():
global frame, frames
frame = Frame(root, highlightbackground="black", highlightthickness=2)
lbl1 = Label(frame, text=f"Frame {len(frames) + 1} label 1")
lbl2 = Label(frame, text=f"Frame {len(frames) + 1} label 2")
lbl1.pack()
lbl2.pack()
frame.pack(padx=5, pady=5)
frame_number = len(frames)
lbl1.bind('<B1-Motion>', lambda event: MoveWindow(event, frame_number))
lbl2.bind('<B1-Motion>', lambda event: MoveWindow(event, frame_number))
frame.bind('<B1-Motion>', lambda event: MoveWindow(event, frame_number))
frames.append(frame)
labels.append(lbl1)
labels.append(lbl2)
def MoveWindow(event, frame_number):
global root, frames
root.update_idletasks()
f = frames[frame_number]
x = f.winfo_width()/2
y = f.winfo_height()*1.5
f.place(x=event.x_root-x, y=event.y_root-y)
root = Tk()
root.geometry("500x500")
frames = []
labels = []
btn = Button(root, text="Open Frame", command=open_frame)
btn.pack()
root.mainloop()

Python: disable and re-enable button

I want to create a button that I can disable and re-enable as soon as I click it. With the following code, I get a button that I can disable, but it won't re-enable when I click it. If looked at this threat, but it didn't help: Disable / Enable Button in TKinter
import tkinter
from tkinter import *
# toplevel widget of Tk which represents mostly the main window of an application
root = tkinter.Tk()
root.geometry('1800x600')
root.title('Roll Dice')
frame = Frame(root)
# label to display dice
label = tkinter.Label(root, text='', font=('Helvetica', 120))
# function activated by button
def switch1():
if button1["state"] == "active":
button1["state"] = "disabled"
else:
button1["state"] = "active"
button1 = tkinter.Button(root, text='Würfel 1', foreground='green', command=lambda: switch1, state = "active")
button1.pack(side = LEFT)
root.mainloop()
Look at this:
import tkinter as tk
def toggle_state():
if button1.cget("state") == "normal":
button1.config(state="disabled")
else:
button1.config(state="normal")
root = tk.Tk()
button1 = tk.Button(root, text="This button toggles state")
button1.pack()
button2 = tk.Button(root, text="Click me", command=toggle_state)
button2.pack()
root.mainloop()
This uses a button to toggle the state of the other button.

How to not open window

from tkinter import *
def firstPage():
def goSecond():
root.destroy()
secondPage()
root = Tk()
text = Label(root, text="1")
text.pack()
btn = Button(root, text="go to 2", command=goSecond)
btn.pack()
root.mainloop()
def secondPage():
def goFirst():
root.destroy()
firstPage()
root = Tk()
text = Label(root, text="2")
text.pack()
btn = Button(root, text="go to 1", command=goFirst)
btn.pack()
root.mainloop()
firstPage()
I made this code and I want it to open a new page, but it open a new window, I understand why but I don't know how to open a page instead of open a window.

How to open a child frame in a single application window in tkinter?

What I want is when I click on a button a new window should get open and that window should be a child of the same main window, But what I am getting is a new Instance of a new window. How do I solve this in tkinter?
Here is the screenshot of what I do not want, Every time a new instance of window is getting is created, I want to make a child instance of same main window:
def login_success():
def c1():
top = Toplevel()
top.title("c1")
top.geometry("1000x600")
def c2():
top = Toplevel()
top.title("c1")
top.geometry("1000x600")
def c3():
top = Toplevel()
top.title("c2")
top.geometry("1000x600")
def write_frames():
top = Toplevel()
top.title("t2")
top.geometry("1000x600")
b1 = Button(top, text="c1", command=c1)
b1.pack()
b2 = Button(top, text="c2", command=c2)
b2.pack()
b3 = Button(top, text="c3", command=c3)
b3.pack()
def write_instructions():
top = Toplevel()
top.title("t1")
top.geometry("1000x600")
root = Tk()
root.geometry("1000x600")
button1 = Button(root,
text="Frames",
command=write_frames)
button1.pack()
button2 = Button(root,
text="Instructions",
command=write_instructions)
button2.pack()
You just have to pass root as a parameter to every function if i understand correctly what you mean
def login_success():
def c1(root):
top = Toplevel(root)
top.title("c1")
top.geometry("1000x600")
def c2(root):
top = Toplevel(root)
top.title("c1")
top.geometry("1000x600")
def c3(root):
top = Toplevel(root)
top.title("c2")
top.geometry("1000x600")
def write_frames(root):
top = Toplevel(root)
top.title("t2")
top.geometry("1000x600")
b1 = Button(top, text="c1", command=lambda: c1(root))
b1.pack()
b2 = Button(top, text="c2", command=lambda: c2(root))
b2.pack()
b3 = Button(top, text="c3", command=lambda: c3(root))
b3.pack()
def write_instructions(root):
top = Toplevel(root)
top.title("t1")
top.geometry("1000x600")
root = Tk()
root.geometry("1000x600")
button1 = Button(root,
text="Frames",
command=lambda: write_frames(root))
button1.pack()
button2 = Button(root,
text="Instructions",
command=lambda: write_instructions(root))
button2.pack()

How to activate tkinter window after destroying the previously one?

I need the next tkinter window to become active automatically after destroying the previous one.
I'm working with Python 3 in Windows 10.
import sys
from tkinter import *
#Green button pressed
def passed():
fails='0'
with open("ButtonPressed.txt",'w')as TestResult:
TestResult.write(fails)
TestResult.close()
root.destroy()
#Red button pressed
def failed():
fails='1'
with open("ButtonPressed.txt",'w')as TestResult:
TestResult.write(fails)
TestResult.close()
root.destroy()
#First window
def PushHold(UUT):
global root
root = Tk()
root.bind('<Return>', lambda q:passed())
TitleText="Push Button test"
root.title(TitleText)
root.geometry("460x160")
frame = Frame(root)
frame.pack()
bottomframe = Frame(root)
bottomframe.pack( side = BOTTOM )
LABLE_TEXT = "Push and hold S1 on "+ UUT+" board.\n Click OK."
label = Label( frame, text=LABLE_TEXT)
label.config(font=("Arial", 22))
label.pack( side = TOP)
greenbutton = Button(frame, text="OK", bg="Green", fg="White", height=2 , width = 10 , command=lambda: passed())
greenbutton.config(font=("Arial", 18))
greenbutton.pack( side = LEFT, padx=140)
root.mainloop()
#Second window
def Release(UUT):
global root
root = Tk()
root.bind('<Return>', lambda q:passed())
TitleText="Release Button test"
root.title(TitleText)
root.geometry("460x160")
frame = Frame(root)
frame.pack()
bottomframe = Frame(root)
bottomframe.pack( side = BOTTOM )
LABLE_TEXT = "Release S1 on "+ UUT+" board.\n Click OK."
label = Label( frame, text=LABLE_TEXT)
label.config(font=("Arial", 22))
label.pack( side = TOP)
greenbutton = Button(frame, text="OK", bg="Green", fg="White", height=2 , width = 10 , command=lambda: passed())
greenbutton.config(font=("Arial", 18))
greenbutton.pack( side = LEFT, padx=140)
root.mainloop()
#read results of the first window
def PushButton(UUT):
PushHold(UUT)
with open("ButtonPressed.txt",'r') as TestResult:
str = list(TestResult)
fails = int(str[0])
TestResult.close()
return fails
#read results of the second window
def ReleaseButton(UUT):
Release(UUT)
with open("ButtonPressed.txt",'r') as TestResult:
str = list(TestResult)
fails = int(str[0])
TestResult.close()
return fails
PushButton('UUT1') #first window calling
ReleaseButton('UUT1') #second window calling
The first window is working good, the second window appears, but not active. It is necessary to click on it to activate before pressing the button.
Trials to use root.withdraw() or root.lift() did not succeed.
On my system the second window takes focus without altering your code, so it is hard to tell. You could probably use root.focus_force() prior to calling root.mainloop()
Alternatively, you could spawn different windows from the same root, using tk.Toplevel.
import sys
from tkinter import *
#Green button pressed
def passed():
fails='0'
with open("ButtonPressed.txt",'w')as TestResult:
TestResult.write(fails)
TestResult.close()
root.destroy()
#Red button pressed
def failed():
fails='1'
with open("ButtonPressed.txt",'w')as TestResult:
TestResult.write(fails)
TestResult.close()
root.destroy()
#First window
def PushHold(UUT):
global root
root = Tk()
root.bind('<Return>', lambda q:passed())
TitleText="Push Button test"
root.title(TitleText)
root.geometry("460x160")
frame = Frame(root)
frame.pack()
bottomframe = Frame(root)
bottomframe.pack( side = BOTTOM )
LABLE_TEXT = "Push and hold S1 on "+ UUT+" board.\n Click OK."
label = Label( frame, text=LABLE_TEXT)
label.config(font=("Arial", 22))
label.pack( side = TOP)
greenbutton = Button(frame, text="OK", bg="Green", fg="White", height=2 , width = 10 , command=lambda: passed())
greenbutton.config(font=("Arial", 18))
greenbutton.pack( side = LEFT, padx=140)
root.focus_force() #<-------------- Here ---------------------
root.mainloop()
#Second window
def Release(UUT):
global root
root = Tk()
root.bind('<Return>', lambda q:passed())
TitleText="Release Button test"
root.title(TitleText)
root.geometry("460x160")
frame = Frame(root)
frame.pack()
bottomframe = Frame(root)
bottomframe.pack( side = BOTTOM )
LABLE_TEXT = "Release S1 on "+ UUT+" board.\n Click OK."
label = Label( frame, text=LABLE_TEXT)
label.config(font=("Arial", 22))
label.pack( side = TOP)
greenbutton = Button(frame, text="OK", bg="Green", fg="White", height=2 , width = 10 , command=lambda: passed())
greenbutton.config(font=("Arial", 18))
greenbutton.pack( side = LEFT, padx=140)
root.focus_force() #<-------------- Here ---------------------
root.mainloop()
#read results of the first window
def PushButton(UUT):
PushHold(UUT)
with open("ButtonPressed.txt",'r') as TestResult:
str = list(TestResult)
fails = int(str[0])
TestResult.close()
return fails
#read results of the second window
def ReleaseButton(UUT):
Release(UUT)
with open("ButtonPressed.txt",'r') as TestResult:
str = list(TestResult)
fails = int(str[0])
TestResult.close()
return fails
PushButton('UUT1') #first window calling
ReleaseButton('UUT1') #second window calling

Resources