I'm trying to make a Tkinter entry of a big size (I want to write multiple paragraphs inside it). I tried to achieve that by increasing ipady and ipadx (entry.grid(row =0, column = 0, ipadx = 50, ipady = 50))and it resulted in a bigger entry, but the text still gets written in only one line and doesn't fill the whole entry. What do you suggest doing?
Here's a screenshot of the entry.
You can use the Text widget
import tkinter as tk
window = tk.Tk()
window.geometry('400x200')
t = tk.Text(window, width=100, height=100)
t.grid(column=1, row=15)
window.mainloop()
Related
It seems that I explained my problem very terribly, but I have a problem with the grid function on my label. The label does show up but, I cant change the row/column of it or do any function inside of the brackets.
I put the code of how to replicate the problem there. Putting anything inside of the .grid() brackets does nothing as stated earlier
from tkinter import *
root = Tk()
#To actually see that it does not work
root.geometry("800x600")
Var = StringVar()
Label = Label(root, textvariable=Var)
#Location of problem, adding stuff into the brackets does not change anything. For example: sticky = "ne"
Label.grid()
Var.set("Ha")
root.mainloop()
To get the label to show up on the right side, you can specify the number of columns in the grid and then place the label in the last column. For example, try adding this just after your "#Location of problem" comment:
cols = 0
while cols < 4:
root.columnconfigure(cols, weight=1)
cols += 1
Label.grid(column=3)
I want to create something like this image, so each time I click the radio button, the column above it is colored blue.
I need guidance on how to get started using tkinter on python
This is my code so far:
from Tkinter import *
the_window = Tk()
def color_change():
L1.configure(bg = "red")
v =IntVar()
R1 = Radiobutton(the_window, text="First", variable=v, value=1, command = color_change).pack()
R2 = Radiobutton(the_window, text="Second", variable=v, value=2, command = color_change).pack()
R2 = Radiobutton(the_window, text="Third", variable=v, value=3, command = color_change).pack()
L1 = Label(the_window,width = 10, height =1, relief = "groove", bg = "light grey")
L1.grid(row = 2, column = 2)
L1.pack()
L2 = Label(the_window,width = 10, height =1, relief = "groove", bg = "light grey")
L2.grid(row = 2, column = 2)
L2.pack() # going to make 10 more rectangles
the_window.mainloop()
I'm just getting started and I don't know what I'm doing.
Programming is more than just throwing code around until something works, you need to stop and think about how you are going to structure your data so that your program will be easy to write and easy to read.
In your case you need to link one button to a list of widgets which need to change when that button is selected. One way to accomplish this is by having a dictionary with keys that represent the button values, and values that are a list of the labels associated with that radiobutton. Note that this isn't the only solution, it's just one of the simpler, more obvious solutions.
For example, after creating all your widgets you could end up a dictionary that looks like this:
labels = {
1: [L1, L2, L3],
2: [l4, l5, l6],
...
}
With that, you can get the value of the radiobutton (eg: radioVar.get()), and then use that to get the list of labels that need to be changed:
choice = radioVar.get()
for label in labels[choice]:
label.configure(...)
You can create every widget individually, or you could pretty easily create them all in a loop. How you create them is up to you, but the point is, you can use a data structure such as a dictionary to create mappings between radiobuttons and the labels for each radiobutton.
I have created an OptionMenu from Tkinter with a columnspan of 2. However, the dropdown list/menu does not match the width, so it does not look good. Any idea on how to match their width?
self.widgetVar = StringVar(self.top)
choices = ['', 'wire', 'register']
typeOption = OptionMenu(self.top, self.widgetVar, *choices)
typeOption.grid(column = 0, columnspan = 2, row = 0, sticky = 'NSWE', padx = 5, pady = 5)
doing drop down name.config(width = width)
works very well with resizing the drop down box.
i managed to get it to work with.
drop1.config(width = 20)
Just letting you know width 20 is quite long.
There is no way to change the width of the dropdown.
You might want to consider the ttk.Combobox widget. It has a different look that might be what you're looking for.
One idea is to pad the right side (or left, or both) with spaces. Then, when you need the selected value, strip it with str strip. Not great, but better than nothing.
from tkinter import ttk
import tkinter as tk
root = tk.Tk()
def func(selected_item):
print(repr(selected_item.strip()))
max_len = 38
omvar = tk.StringVar()
choices = ['Default Choice', 'whoa', 'this is a bit longer'] + ['choice'+str(i) for i in range(3)]
padded_choices = [x+' '*(max_len-len(x)) for x in choices]
om = ttk.OptionMenu(root, omvar, 'Default Choice', *padded_choices, command=func)
om.config(width=30)
om.grid(row=0, column=0, padx=20, pady=20, sticky='nsew')
root.mainloop()
this answer is a little bit late but I thought in case other people are searching for it, here is my solution:
optionMenu1 = ttk.OptionMenu(btnPane, item_text, item_text.get(), "Choose item!\t\t\t\t\t\t\t\t",
*list1, *list2(), style='Custom.TMenubutton')
what I am doing here is to only set the default-value with a lot of tabs (\t). The reason for this is that all items of the dropdown are getting the same width. The width of the longest item. In this case its the Default. Now you can get the value of the other items without stripping something. And your width has changed.
How much tabs you need will you see if you test it (depending on the width of your OptionMenu).
Hope it helps someone.
Regards
Just use config()
typeOption.config(width = 50)
We can change the dropdown width by writing as follows:
typesOfSurgeries = ['Chemotherapy','Cataract']
listOfSurgeries = tkinter.OptionMenu(test_frame, variable, *typesofSurgeries)
listOfSurgeries.config(width=20)
listOfSurgeries.grid(row=14,column=1)
listOfSurgeries.config(width=20) sets the width of the OptionMenu
Firstly let's look at this program:
def entry_simutaneously_change():
from Tkinter import *
root=Tk()
text_in_entry.set(0)
Entry(root, width=30, textvariable= text_in_entry).pack()
Entry(root, width=30, textvariable= text_in_entry).pack()
Entry(root, width=30, textvariable= text_in_entry).pack()
root.mainloop()
The contents in these three entries can change simultaneously. If I change the value of any of them, the other two would change at the same time. However, for the following program:
def entry_simutaneously_change():
from Tkinter import *
root=Tk()
text_in_entry_list=[IntVar() for i in range(0,3)]
text_in_entry_list[0].set(0)
text_in_entry_list[1].set(text_in_entry_list[0].get() ** 2)
text_in_entry_list[2].set(text_in_entry_list[0].get() ** 3)
Entry(root, width=30, textvariable= text_in_entry_list[0]).pack()
Entry(root, width=30, textvariable= text_in_entry_list[1]).pack()
Entry(root, width=30, textvariable= text_in_entry_list[2]).pack()
root.mainloop()
When I change the content in the first entry, the contents in the other two do not change. Why?
In the first program, you have one source of data, text_in_entry. You could consider it as one box where you're placing a single value that's read by each Entry.
In the second program, you have three sources of data, text_in_entry[0, 1, and 2]. The lines that set the initial value are called only once. It's like you have three boxes where data is placed; to set the initial values, you do look at the value inside the first, but there is no association between the three.
If you would like to achieve the same type of result as with the first program (when the three entries update simultaneously) then you will need to bind on an event. I note that Tkinker does not have an on-change style event but there are various hacks, however you could bind to the FocusOut event. The general idea is to ask for a function to be called when a change occurs to an entry (binding a callback). Inside that function you update the other two values based on the new value in the entry that was changed.
I have the following sections of code (not complete) where I would like to contain several frames into a single tab in the ttk 'Notebook' .
win1 = Tk()
n = ttk.Notebook(win1)
choice_frame = ttk.Frame(n, style="Black.TLabel")
choice_frame.grid(row=2, column=1, sticky="N,S,E,W", padx=1, pady=1)
choice_frame.grid_columnconfigure(0, weight=3)
choice_frame.grid_rowconfigure(0, weight=1)
frame_text = ttk.Frame(n, style="Black.TLabel")
frame_text.grid(row=0, column=0, sticky = "N")
frame_text.grid_columnconfigure(0, weight=3)
frame_text.grid_rowconfigure(0, weight=1)
frame_table = ttk.Frame(n, style="Black.TLabel")
frame_table.grid(row=2, column=0, padx=1, pady=1, sticky= " N, S, E, W ")
frame_table.grid_columnconfigure(0, weight=3)
frame_table.grid_rowconfigure(0, weight=1)
n.add(frame_table, text="One") # Would like same tab not two separate ones
n.add(choice_frame, text="One")
n.grid(sticky="N")
I would also like to know if there's a way of allowing every dimension to adjust automatically when the window is dragged out and maximised. I have previously tried:
frame_table.grid_propagate(0)
But this doesn't seem to allow the height as well as width dimension to stick. I would like my 'table' to be in the center of the window but adjust with the window size.
Thank you for your help!
grid_propagate isn't a solution to any of your problems.
Each tab can contain only a single frame, but that single frame can contain whatever you want. So, create one container frame for the tab and then put all your other frames in the container frame. This is one of the main reasons the Frame class exists -- to build widget containers that facilitate layout.
As for the resizing, the problem is probably that you're not adding a weight to the rows and columns of the main window. Though it could also be related to the fact you are using grid to place the frames in the notebook; you can't use grid to place items in a notebook.