Can't put buttons on second window using Tkinter - python-3.x

I don't know why is the window created with nothing when I've put 3 buttons to appear. This is the function where it happens:
def Click():
if input_fieldContra.get() == contraseña:
vent_iniciada = Tk()
root.withdraw()
vent_iniciada.geometry("250x200")
vent_iniciada.mainloop()
nuevoB = Button(vent_iniciada, text="Nuevo", command=NuevoBot)
abrirB = Button(vent_iniciada, text="Abrir", command=AbrirBot)
guardarB = Button(vent_iniciada, text="Guardar", command=GuardarBot)
nuevoB.grid(vent_iniciada, row=0, column=0)
abrirB.grid(vent_iniciada, row=2, column=0)
guardarB.grid(vent_iniciada, row=3, column=0)

Firstly, .grid() doesn't take on the parent window. When using grid you should define the parent window inside the widget when widget is created.
.grid() options must be -column, -columnspan, -in, -ipadx, sticky etc.
Secondly, if you move vent_iniciada.mainloop() to the bottom of the code, it should work. What happens is that the code is executing:
vent_iniciada = TK()
root.withdraw
vent_iniciada.geometry("250x200")
and this is where you should put your button so the code reads them into the window.
Finally, after gridding the widgets, you tell the program to mainloop everything
vent_iniciada.mainloop()

You have to move :
vent_iniciada.mainloop()
to the last line of the function

Related

How to work with multiple windows in Tkinter

I want to have 2 tkinter Windows. On the main Window there should be a button which opens a new window and closes the original one. Below you can see my minimal Code example.
So far the first window opens but as soon as I push the button both windows just close.
Please tell me what my specific error is int this code?
Is there a way to emprove my code?(general tips)?
.
def Func_Show_Rep(self):
#destroy main window
Cockpit_Win.quit()
Cockpit_Win.destroy()
# Open new Window
ReportSelection_Win = Toplevel()
ReportSelection_Win = Tk()
#create the main window
Cockpit_Win = Tk()
Btt_Show_Rep = Button(Cockpit_Win, text="Reports", width=35)
Btt_Show_Rep.bind("<Button-1>",Func_Show_Rep)#Button click starts function
Btt_Show_Rep.grid(column=1, row=2, padx=10, pady=7, sticky=E)
#Make the windows stay (loop)
Cockpit_Win.mainloop()
You cannot have a TopLevel window when the root window is destroyed with Tkinter. The TopLevel window is built on top of the root window.
If you want to destroy (effectively hide) the Cockpit_Win window, use the following:
Cockpit_Win.withdraw()
When you want to make it visible again, use:
Cockpit_Win.deiconify()
The entire code looks like this:
def Func_Show_Rep(self):
# Open new Window
ReportSelection_Win = Toplevel()
#ReportSelection_Win = Tk() # This is the same as the previous statement
#destroy (effectively hide) main window
Cockpit_Win.withdraw()
#create the main window
Cockpit_Win = Tk()
Btt_Show_Rep = Button(Cockpit_Win, text="Reports", width=35)
Btt_Show_Rep.bind("<Button-1>",Func_Show_Rep)#Button click starts function
Btt_Show_Rep.grid(column=1, row=2, padx=10, pady=7, sticky=E)
#Make the windows stay (loop)
Cockpit_Win.mainloop()

"Sticky" paramter doesnt change the window at all

I am just building my first tkinter window and I am a little puzzled. I created a label and a Button and set them in them same row but different columns.
Now the placement of the button changes depending on the length of the text in the label. To fix this I wanted to "stick" the label and the button to east/west respectively and add a small amount of padding.
Now the issue, no matter what variant of "sticky" I add it doesn't affect the placement of anything at all.
Below are the two code variants that all lead to the same output window:
from tkinter import *
def Btt_ShowAll_clicked():
print("klicked")
#create the window
Main_Window = Tk()
#Modify the Window
Main_Window.title("Ressourcen Verwaltung")
Lbl_Descr_a = Label(Main_Window, text = "Einträge einsehen")#Create Label
Lbl_Descr_a.grid(column=0, row=0, padx=10) #Show Label
Btt_ShowAll_a = Button(Main_Window, text="Einträge anzeigen")
Btt_ShowAll_a.bind("<Button-1>",Btt_ShowAll_clicked)#Button click starts function
Btt_ShowAll_a.grid(column=1, row=0, padx=10, pady=10, sticky=W)
#In the line above Change "W" to "E" ord delet the "sticky = W" alltogether and nothing changes in the window
Main_Window.geometry('350x200') #Window size
#Make the windows stay (loop)
Main_Window.mainloop()
What can I do to get the desired output?
Shouldn't "sticky" stick it to the given side and then with padx I should be able to choose how close it is said side?
As far as I know, you have to type sticky='w' instead of sticky=W, should work then.

How to put an object in a specefic row or column while using pack in tkinter

I have been making some gui applications using python tkinter.In tkinter pack and grid cannot be used together.While writing a code I had to use pack and then I needed to use 2 features called 'Cloumn' and 'row' of grid but that is impossible.
from tkinter import *
root = Tk()
button = Button(root, text="Click Me")
button.pack(side="bottom") #But I want to put that button in row=3
root.mainloop()
I need to put that button in row number 3.But how can I do it?
Is there any way to do so?
In order for pack and grid to be used in the same code you need to make sure you use them on separate containers. Each container (root window, toplevel window, frame) can only have either grid() or pack().
For example if I need to use pack on a frame and then use grid inside of that frame that is ok. But I cannot use pack inside the frame and also grid inside the frame.
If you expand the window made from the below code you will see how pack and grid can work together if used properly.
import tkinter as tk
root = tk.Tk()
top_frame = tk.Frame(root)
top_frame.pack(sid="top")
bot_frame = tk.Frame(root)
bot_frame.pack(sid="bottom")
tk.Label(top_frame, text="Row 0 of top_frame").grid(row=0, column=0)
tk.Label(bot_frame, text="Row 0 of bot_frame").grid(row=0, column=0)
tk.Label(bot_frame, text="Row 1 of bot_frame").grid(row=1, column=0)
tk.Label(bot_frame, text="Row 2 of bot_frame").grid(row=2, column=0)
tk.Button(bot_frame, text="Row 3 of bot_frame").grid(row=3, column=0)
root.mainloop()

Why the tkinter window does not open when using the method "grid()"?

from tkinter import *
# ==================================================Settings=======================================================
root = Tk()
root.title("Video Youtube Downloader") # set up the title and size.
root.configure(background='black') # set up background.
root.minsize(800, 500)
root.maxsize(800, 500)
# ==================================================Frames=======================================================
top = Frame(root, width=800, height=50, bg='yellow').pack(side=TOP)
bottom = Frame(root, width=800, height=50, bg='red').pack(side=BOTTOM)
left = Frame(root, width=550, height=450, bg='black').pack(side=LEFT)
right = Frame(root, width=250, height=450, bg='blue').pack(side=RIGHT)
# ==================================================Buttons=======================================================
btn_clear_url = Button(right, text="Clear Url", font=('arial', 10, 'bold')).grid(row=1, columns=1)
I am trying to add buttons to the right Frame, but for some reason when I run the program the IDE shows that it is running but there is
no window. When I delete .grid(row=1, columns=1) the window appears.
How can I fix this bug, and add btn_clear_url button to the right Frame?
First of all, you need to invoke Tk's mainloop at the end of your code (you can see here why).
Another problem is chaining method calls like that. You're actually assigning return value of the last call to the variable, which is None in case of grid() and pack() - therefore, all your variables end up having None as the value. You need to separate widget instantiating call and grid or pack call and put each on its own line.
Other than that, you're setting both minsize and maxsize to the very same size - if you're really just trying to make your window not resizable, set the size with:
root.geometry('800x500') # for instance
...and after that configure resizable attribute:
root.resizable(width=False, height=False)
Also, I suggest you get rid of from tkinter import *, since you don't know what names that imports. It can replace names you imported earlier, and it makes it very difficult to tell where names in your program are supposed to come from. Use import tkinter as tk instead.
When you place widget in a tk window you cannot use grid and pack at the same time in the same window, so you use should use pack () instead of grid()
The problem starts with this line of code:
right = Frame(root, width=250, height=450, bg='blue').pack(side=RIGHT)
With that, right is set to None because .pack(side=RIGHT) returns None.
Next, you do this:
btn_clear_url = Button(right, ...)).grid(row=1, columns=1)
Because right is None, it's the same as Button(root, ...). Since you are already using pack for a widget in root, you can't also use grid.
The solution -- and best practice -- is to separate widget creation from widget layout:
top = Frame(root, width=800, height=50, bg='yellow')
bottom = Frame(root, width=800, height=50, bg='red')
left = Frame(root, width=550, height=450, bg='black')
right = Frame(root, width=250, height=450, bg='blue')
top.pack(side=TOP)
bottom.pack(side=BOTTOM)
left.pack(side=LEFT)
right.pack(side=RIGHT)
With the above, right will be properly set to the frame instance, and adding a widget to right and using grid will no longer fail.

Raise Frame on top in PanedWindow in tkinter python 3.5

I have a frame in PanedWindow which i need on every tkinter GUI (in this case it's topFrame). Below it are many frames and I want to switch between those frame on button click (just like in any software where the top portion of screen is fixed and clicking on buttons the lower portion of GUI changes).
I know i need grid layout for it. But, it is not happening and i am not getting a solution anywhere.I have researched a lot on this topic everywhere but this solution is nowhere. Here is my code... i have written in comments those code which i feel are not working fine.
#python 3.5
from tkinter import *
#function to raise the frame on button click
def raiseFrame(frame):
frame.tkraise()
m = PanedWindow(height=500, width=1000, orient=VERTICAL)
m.pack(fill=BOTH, expand=1)
#to expand the column and row to fill the extra space
m.grid_columnconfigure(index=0, weight=1) #this code is not working as it should
m.grid_rowconfigure(index=0, weight=1) #this code is not working as it should
#top frame has two buttons which switches the bottom frames
topFrame = Frame(m, bg="blue")
m.add(topFrame)
button1 = Button(topFrame, text="Raise Frame 2", command=lambda: raiseFrame(frame2)) #raises frame 2 on clicking it
button1.pack(side=LEFT)
button2 = Button(topFrame, text="Raise Frame 1", command=lambda: raiseFrame(frame1)) #raises frame 1 on clicking it
button2.pack(side=LEFT)
#bottomframe acts as container for two other frames which i need to switch
bottomframe = Frame(m, bg="orange")
m.add(bottomframe)
frame1 = Frame(bottomframe, bg="yellow")
frame1.grid(row=0, column=0, sticky="news") ## sticky is not working ##
frame2 = Frame(bottomframe, bg="green")
frame2.grid(row=0, column=0, sticky="news") ## sticky is not working ##
label1 = Label(frame1, text="i should change")
label1.pack(padx=10, pady=10)
label2 = Label(frame2, text="i am changed !!")
label2.pack(padx=10, pady=10)
mainloop()
1)Please correct my code.
2)Explain me why in the "topFrame" even though i have not written
topFrame.pack(fill=BOTH, expand=True)
my code is showing the above property and it's expanding as well as filling both X and Y.
Same goes for the bottomFrame, it's orange colour is filling the entire space which does not happen in normal frames. So, is it some special feature of PanedWindow ?
You don't want to call topFrame.pack() and m.add(topFrame). You either pack/place/grid the window, or you add it to a paned window, you don't do both.
Also, if the frame is going to be in the paned window it needs to be a child of the paned window rather than a child of the root window.

Resources