How to use widgets inside a tkinter frame using grid? - python

I am using tkinter Frames to divide the window and I have bound Frames using grid.
Now When I bind the widgets inside a frame using .grid(), it come out of frame automatically and get bound to main tkinter window.
If I use .pack(), it says : _tkinter.TclError: cannot use geometry manager pack inside . which already has slaves managed by grid
from tkinter import *
root = Tk()
myFrame = Frame(root,text="Frame1").grid(row=1,column=1)
MyLabel = Label(myFrame,text="Label inside Frame1").pack()
Any other method to bind widgets inside frame?

This is a side effect from laying out a widget on the same line as defining it. It causes the widgets to default to root. Try this:
from tkinter import *
root = Tk()
myFrame = Frame(root,text="Frame1")
myFrame.grid(row=1,column=1)
MyLabel = Label(myFrame,text="Label inside Frame1")
MyLabel.pack()

Related

Why is my button working even though I haven't assigned any parent window to it?

Why is my button working even though I haven't assigned any parent window to it?
from tkinter import *
root = Tk()
Button(text='MyButton').pack()
root.mainloop()
Widgets live in a tree-like hierarchy with a single widget acting as the root of the tree. The root widget is an instance of Tk and should be explicitly created by the application before any other widget.
All widgets except the root window require a master. If you do not explicitly define the master for a widget it will default to using the root window.
You can turn this behavior off by calling the function NoDefaultRoot from the tkinter module. For example, the following code will fail with AttributeError: 'NoneType' object has no attribute 'tk':
from tkinter import *
NoDefaultRoot()
root = Tk()
Button(text='MyButton').pack()
root.mainloop()

How to set ‘in' attribute in ' pack' method (tkinter library)?

from tkinter import *
window=Tk()
Button(window,text='').pack(in=?)
How to set 'in' attribute in pack method? what does that mean?
I looked at the source code of the pack, but I still couldn't understand how to set the ’in' attribute about pack method.
How to set 'in' attribute in pack method?
You must use in_ rather than in. For example:
root = tk.Tk()
frame = tk.Frame(root)
button = tk.Button(root)
button.pack(in_=frame)
what does that mean?
When laying out a widget, every widget except the root window has a master -- some other widget which contains the widget and which controls how it is laid out. By default the master is the same as the parent. For example, if you do Button(window,text=''), the parent of the button is window, and thus its master will also default to window.
You can use in_ to change the master. For example, you could make a button be the child of the root window, but be laid out in some other frame. In the earlier example, the button is a child of the root window but will be a slave inside of the frame.
This is something you almost never need to do with tkinter, since it's usually preferable to have the parent and the master be the same widget.

Python tkinter placing a button in a grid inside a frame freezes on execution

I have created two frames using Tkinter. In one of the frames I am trying to add a button using a grid. When I run the program, there is no output. Instead it just freezes and I have to kill the process.
Here is the code:
from Tkinter import *
window=Tk()
window.title("calculator")
window.geometry("500x500")
window.resizable(0,0)
input_field=StringVar()
display_frame=Frame(window).pack(side="top")
button_frame=Frame(window).pack(side="bottom")
text=Entry(display_frame,font=('arial',20,'bold'),textvariable=input_field,justify="right").pack(fill="x",ipady=10)
clear_button=Button(button_frame,text="C").grid(row=0)
window.mainloop()
However, if I change the clear_button variable as
clear_button=Button(button_frame,text="C").pack()
I get an output. What am I missing here?
You cannot mix grid and pack inside the same container (a Frame/Window).
That said you should realize that your display_frame and button_frame variables are actually None! Why, because Frame(Window) will return a Frame object, but you have applied the pack() function just after that whose return value is None.
So basically the Entry and the Button widgets that you created have master=None and that means they are not inside the Frames that you defined, but actually part of the main Window.
Now you can easily see why clear_button=Button(button_frame,text="C").pack() was working as now the main window has only one geometry manager namely pack.
Here is the working code.
from tkinter import * # "Tkinter" on python 2
window=Tk()
window.title("calculator")
window.geometry("500x500")
window.resizable(0,0)
input_field=StringVar()
display_frame=Frame(window)
display_frame.pack(side="top")
button_frame=Frame(window)
button_frame.pack(side="bottom")
Entry(display_frame,font=('arial',20,'bold'),textvariable=input_field,justify="right").pack(fill="x",ipady=10)
Button(button_frame, text="C").grid(row=0)
window.mainloop()
You cannot use both grid and pack method on widgets having same master.
Here, follow the below thread for a detailed understanding :
python pack() and grid() methods together

frame widget in tkinter prevents child widgets from being displayed

I have been trying to get to grips with tkinter as a gui builder in python.
I used a textbook tutorial to create the following which uses a frame widget to hold other widgets (suggested by author):
from tkinter import *
root = Tk()
app = Frame(root)
lbl = Label (app, text="This is a label")
lbl.grid()
root.mainloop()
This creates a window but the lbl object isn't created at all. I have found precious little online but in testing I did discover that if I removed setting up the frame and just passed root as the master directly into the label constructor it worked.
The tkinter.Frame widget needs to have its grid method called as well:
app = Frame(root)
app.grid()
Otherwise, it will not be placed on the window.

label layout using grid in tkinter

I'm having some trouble figuring out how to use grid properly with tkinter. I just want two labels to appear side by side.
When I do the following, they appear in a separate window from my app. I'm confused because I have buttons on my app that appear as I want them(not using grid), but I can't quite figure out the labels in a grid.
//this is just a snippet from a function
self.root = tk.Tk()
tk.Label(master=self.root, text=directory).grid(row=0,column=0)
tk.Label(master=self.root, text=directory).grid(row=0,column=1)
The root window is created in a different part of the app, so all I'm doing here is making another one (I think). I just want the labels to appear in the window that has already been created but I can't figure out what I'm supposed to reference it to.
This is in a separate file that includes the file with the code above
from Tkinter import *
import tkinter as tk
import widgetActions
import shutil
class mywidgets(widgetActions.Actions):
def __init__(self,root):
frame = tk.Frame(root)
self.makeMenuBar(frame)
frame.pack()
frame.config(width=400)
self.body()
return
def makeMenuBar(self,frame):
menubar = Frame(frame,relief=RAISED,borderwidth=1)
menubar.pack()
mb_file = Menubutton(menubar,text='file')
mb_file.pack(side=LEFT)
mb_file.menu = Menu(mb_file)
mb_file.menu.add_command(label='open', command = self.openfile)
mb_file.menu.add_command(label='close', command = menubar.quit)
mb_file['menu'] = mb_file.menu
return
def body(self):
self.filename()
def main():
root = tk.Tk()
k=mywidgets(root)
root.title('menu bar')
root.mainloop()
main()
You cannot create two instances of Tk. As you observed, you will get two windows. That's not the only problem, just the most obvious one.
You need to pass in a reference to the winget that is to contain these labels. Or, store the root window as a global variable, or as an attribute of an object.
To position the 2 labels side by side i.e label1 and label2:
label1.grid(column=0, row=0)
label2.grid(column=1, row=0)
That should do it

Categories