How to place radiobuttons horizontal in python - 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.

Related

Typing in one entry causes all entries to be written into (Tkinter)

I'm creating a sudoku solver desktop application with a GUI using Tkinter. The issue I'm having is when it comes to inputting the board.
Here is the code I'm using:
N = 9
input = [["0" for i in range(N)] for j in range(N)]
for i in range(N):
for j in range(N):
new_col = int(j/3)
new_row = int(i/3)
if (-1)**(new_col+new_row) == 1:
colour = "lightgrey"
else:
colour = "white"
entry = Entry(root, width=10, bg=colour, textvariable=input[i][j])
entry.grid(row=i, column=j)
set_button = Button(root, text="Set", command=set, padx=20, pady=10).grid(row=10,column=3, columnspan=3)
The set button is used to set the values and then display the actual board.
The issue I'm having is that typing in any one of the boxes causes the same value to be typed into every other box. I don't understand how this is happening. Is my array declaration at fault maybe?
Also, I checked and the array is unchanged even after clicking set.
Consider this line of code:
entry = Entry(root, width=10, bg=colour, textvariable=input[i][j])
Because of the way you've initialized input, the above code is the same as this:
entry = Entry(root, width=10, bg=colour, textvariable="0")
Thus, all widgets have the same value for textvariable so they are all linked together and share the same memory for the value.
Each entry needs a unique textvariable, and the value of that option needs to be a tkinter variable object such as StringVar.
That being said, you rarely need to use textvariable. Since you aren't adding a trace to the variables, they are largely unnecessary. I recommend you remove the textvariable and instead save your entry in your array. You can then call the get method of the entry to get the value.

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

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.

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.

How can i display a 3x3 grid in Python tkinter?

For a program i intend to develop, its essential for me to develop a 3x3 grid which will display words from a set which has been converted to a list. To achieve this I'm aware of a method which will supposedly create a 3x3 grid using a list with linebreaks already within the developed list. However, my program functions at a more diverse level and instead of having a pre-defined text file / list, my set/list is defined by the users input and utalises a file dialog which allows the user to select their own 9 words for the 3x3 grid. For this reason i dont think its possible to apply the line breaks. Is there another way i could display a 3x3 grid which displays each of these 9 words. Would be extremely grateful of any advice given. As for code... if anyone feels that any particular section of code would help them solve this problem, do not hesitate to leave a comment. Thank you very much!
Creating a 3x3 grid is no more difficult than looping over items and creating widgets.
This creates a 3x3 grid of labels, storing references to the widgets in a dictionary:
table = tk.Frame(root)
for row in range(3):
for col in range(3):
label = tk.Label(table, text="")
label.grid(row=row, column=col, sticky="nsew", padx=1, pady=1)
table[(row, col)] = label
You can then modify any of the cells of the table using the configure method of the label widget. For example, this sets the middle cell to "Hello":
table[(1,1)].configure(text="Hello")
oyoy, i see dis,
table = tk.Frame(root)
for row in range(3):
for col in range(3):
label = tk.Label(table, text="")
label.grid(row=row, column=col, sticky="nsew", padx=1, pady=1)
table[(row, col)] = label

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