Tkinter: Why is the next 'Label' taking it's 0 column differently? - python

label = tk.Label(window, text="Guess a number that can be anything from '10' to '50', you have 5 chances !!!", fg="black", bg="white", font=("Arial Bold", 25))
label.grid(row=0)
inp = tk.Entry(window)
inp.grid(row=1)
Output Should Be Something Like this:
Guess a number that can be anything from '10' to '50'...
Input Field
but its:
Input field is away from the centre, why?

Use Sticky
import tkinter as tk
window =tk.Tk()
label = tk.Label(window, text="Guess a number that can be anything from '10' to '50', you have 5 chances !!!", fg="black", bg="white", font=("Arial Bold", 25))
label.grid(row=0)
inp = tk.Entry(window)
inp.grid(row=1,sticky="w")
window.mainloop()

Column zero has a very wide label in it which forces the column to be as wide as the label. The entry widget is in that same very wide column, and by default grid centers items in the column.
If you want the entry widget aligned to the left, you can use the sticky option to force the widget to "stick" to the west (left) side of the column.
inp.grid(row=1,sticky="w")
If these are the only two widgets in the UI, this is probably the right solution. If you plan to have other widgets aligned with either the label or the entry widget, you may need to do something else. Without knowing more about the final product it's hard to say for sure.
Another solution would be to configure the label to span two columns, and have the second column be given all of the extra space. That will cause the first column to be as small as necessary.
label.grid(row=0, columnspan=2)
window.grid_columnconfigure(1, weight=1)
The choice depends a bit on what else you plan to do with the window. If you're only going to have these two widgets and nothing else, the first solution requires one less line of code. The second solution makes it easier to add other widgets on the same row as the entry widget.

Related

How can I make an another block of items under a grid in tkinter? - Python

I want to make a 'maze' game with tkinter, and I wanted to display some things under the grid(game area), and this happend:
Because I wanted to put the text in the last line and the first column of the grid.
frame = tk.Frame(window)
frame.grid(row=line+1, column=0)
label = tk.Label(master=frame, text="Dashing:")
label.pack()
Any ideas, how can I fix this?
Make the frame span all of the columns:
frame.grid(row=line+1, column=0, columnspan=17)

Python - Tkinter fix object position

Im currently testing around with python GUI and have made a script that takes 2 entered numbers from 2 textfields and upon a button press generates a block of labels (e.g. i enter 4 and 5 so it generates a 4x5 field of labels)
but now i want to do this: when i generate objects, i want to prevent them to
- move
- overlap
my current objects (buttons, textfields).
i can kind-of figure something for the overlapping, but every time i generate new stuff, everything moves around. Can i set a specific field in the grid to be "reserved" so that new stuff never goes in there?
this is my current attempt - as you can see, its not overlapping anymore, but if the snowflakes are generated, the textboxes and buttons still "jump" apart for a small distance
EDIT: the "jumps" are due to the font size of the added snowflakes - that still leaves my question on how i prevent this, as i dont want to be limited to small font sizes
from tkinter import *
wide = 0
deep = 0
entrytext = "test"
window = Tk()
window.title("test")
window.geometry('1000x1000')
ent = Entry(window)
ent.grid(column=0, row=1)
def GetClicked():
global wide
wide = ent.get()
wide = int(wide)
btn2 = Button(window, text="Width", command=GetClicked)
btn2.grid(column=0, row=2)
ent2 = Entry(window)
ent2.grid(column=0, row=3)
def GetClicked2():
global deep
deep = ent2.get()
deep = int(deep)
btn = Button(window, text="Depth", command=GetClicked2)
btn.grid(column=0, row=4)
def WingBut(column,row):
lbl = Label(window, text="T", font=("Wingdings", 15))
lbl.grid(column=column, row=row)
def clicked(wide,deep):
h = 0
j = 0
while h in range (deep):
i = 0
h += 1
while i in range(wide):
if i > 2 or j > 5:
WingBut(i,j)
i += 1
if i == wide:
j += 1
btn = Button(window, text="Buttonspam",font=("Arial", 10),command=lambda: clicked(wide,deep))
btn.grid(column=0, row=0)
window.mainloop()
the textboxes and buttons still "jump" apart for a small distance
This is due to the resulting size of the dynamically added labels (those labelled "T") being taller than the current row height for each row. Because the row size must increase to accommodate the new label, the other widgets in the same row are also resized so that the overall height for the row is consistent. That resize is causing the jumping effect.
One way to correct it would be to reduce the font size of the "T" labels. Try setting it to 10 and the problem should go away.
Another way to solve it would be to set the minsize for each row to be the height of the tallest widget in the row, e.g. the "T" label widget height.
for row in range(5):
window.rowconfigure(row, minsize=36)
You can add the above code before you call window.mainloop().
I selected 36 because this makes the rows a minimum of 36 pixels high, and this is sufficient on my system to display the "T" without causing the row to resize.
If you don't want to hardcode the minsize you could calculate it dynamically.
dummy = Label(window, text="T", font=("Wingdings", 20))
dummy.grid(row=0, column=0)
dummy.update_idletasks() # seems to be required to get rendered size
height = dummy.winfo_height()
dummy.grid_forget() # we don't want users seeing this widget
for row in range(5):
window.rowconfigure(row, minsize=height)
That's one way to do it. Possibly there is a better, more direct, way using the font itself, but you can research that if you're interested.

How to place radiobuttons horizontal in python

AANTAL = [(1,"1"),(2,"2"),(3,"3"),(4,"4"),(5,"5"),(6,"6"),]
v= StringVar()
v.set("1")
for text, mode in AANTAL:
but = Radiobutton(Main,padx=20, pady=10,font=('arial', 20, "bold"), bd=4, text=text, variable=v, value=mode, indicatoron=0)
but.grid()
The above code shows some radiobuttons numbered 1 to 6. However, it displays them vertically instead of horizontally. Does anyone know how I could fix this?
I already tried putting row=0 in the grid command but this only stacks the buttons on top of each other instead of spreading them out over a row.
grid has two options for placing a widget. row and column. You need to specify both.
buttons = []
vars = []
for idx, (text, mode) in enumerate(AANTAL):
vars.append(StringVar(value="1"))
buttons.append(Radiobutton(Main,padx=20, pady=10,font=('arial', 20, "bold"), bd=4, text=text, variable=vars[-1], value=mode, indicatoron=0))
buttons[-1].grid(row=0, column=idx)
Also, when using loops to create widgets, it is much better to store them in a list because you can access them later in your program.

Second row entry width affect the first row style in tkinter?

I'm trying to create the some sample application.
Which first row is One label then input entry box then submit button.
Then second row has the another entry box.
My problem is when I increase width of the entry box in second row it affect the first row style. I don't know what is the problem.
import Tkinter
tk_obj = Tkinter.Tk()
tk_geo = tk_obj.geometry("1200x800")
Tkinter.Label(tk_obj, text='Enter query ').grid(row=1,column=1)
def callback():
print "hi"
E1 = Tkinter.Entry(tk_obj,bd=3,width=120)
E1.grid(row=1, column=2,ipady=3)
b = Tkinter.Button(tk_obj, text="Check", command=callback)
b.grid(row=1,column=3)
E2 = Tkinter.Entry(tk_obj,bd=3,width=100)
E2.grid(row=2,column=1,ipady=100)
tk_obj.mainloop()
The grid method places widgets in the center of the cell they inhabit. When you have two widgets of different sizes sharing a row or column, this means that there will be blank space around the smaller widget. To make the second Entry widget span the first two columns, use columnspan=2 when you grid() it. To left-align it within those two columns, use sticky='W':
E2.grid(row=2,column=1,ipady=100, columnspan=2, sticky='W')
You can then adjust that Entry widget's width attribute until it looks the way you want it to.

Aligning widgets using grid between multiple Tkinter LabelFrames

I'm trying to create a Tkinter layout that has labels and entry fields vertically aligned across multiple LabelFrame boxes.
Here's some simplified code:
#!/usr/bin/python
from Tkinter import *
win = Frame()
win.grid(sticky=N+S+E+W)
frame_a = LabelFrame(win, text='Top frame', padx=5, pady=5)
frame_b = LabelFrame(win, text='Bottom frame', padx=5, pady=5)
frame_a.grid(sticky=E+W)
frame_b.grid(sticky=E+W)
for frame in frame_a, frame_b:
for col in 0, 1, 2:
frame.columnconfigure(col, weight=1)
Label(win, text='Hi').grid(in_=frame_a, sticky=W)
Label(win, text='Longer label, shorter box').grid(in_=frame_b, sticky=W)
Entry(win).grid(in_=frame_a, row=0, column=1, sticky=W)
Entry(win, width=5).grid(in_=frame_b, row=0, column=1, sticky=W)
win.mainloop()
The above code produces a window that looks like the below:
Whereas I'm looking to find some way of aligning the fields so the window looks more like this (with thanks to MS Paint):
I've played around with in_ arguments to grid(), but not achieved very much, and I can't think of anything else to experiment with.
The short answer is: you can't do what you want. grid does not manage its rows and columns across multiple containers.
However, there are at least a couple ways to achieve the effect you are wanting. One way is to give the first column in each container an explicit, identical width. To do that you can use the grid_columnconfigure method to give each column a minimum width.
Another solution is to give each label an identical width, which effectively will set the width of the first column to be the same (assuming all columns in each container have the same weight).
The easiest way I know to do what you want, is to change the make the Label text variables, and then, check the len(txt1) against len(txt2), and, set the width variable of both to the longest one. The following code is close. My knowledge is too limited to figure out where the extra space is coming from.
txt1 = StringVar()
txt2 = StringVar()
lblWidth = IntVar()
txt1 = "Hi"
txt2 = "Longer label, shorter box"
if (len(txt1) > len(txt2)):
lblWidth = len(txt1)
else:
lblWidth = len(txt2)
Label(win, text=txt1, width=lblWidth, anchor=W).grid(in_=frame_a)
Label(win, text=txt2, width=lblWidth, anchor=W).grid(in_=frame_b, sticky=W)

Categories