Python Tkinter: OptionMenu modify dropdown list width - python

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

Related

Write Multiple Lines in Tkinter Entry

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()

Certain label wont work with .grid() function from tkinter

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)

tkinter link radio button to more than one label and change color

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.

Python tkinter create buttons with loop and edit their parameters

I'm making a program with Tkinter where I'd need to use a "for i in range" loop, in order to create 81 Text Widgets named like :
Text1
Text2
Text3
...
and dispose them in a square (actually to make a grill for a sudoku game of a 9*9 size). After I created these 81 Text Widgets I need to place them (using .place() ) and entering their position parameters.
After this, I will need to collect the values that the user entered in these Text Widgets.
I'm a newbie and I don't really know how to code this.
Here is my actual code but the problem is I can't modify the parameters once the dictionnary is created and i don't know how to access to the Text Widgets parameters. Maybe using a dictionnary is not the appropriate solution to do what I want.
d = {}
Ypos = 100
for i in range(9):
Xpos = 100
for j in range(9):
d["Text{0}".format(i)]= Text(window, height=1, width=1,relief = FLAT,font=("Calibri",16))
d["Text{0}".format(i)].place(x = Xpos+,y = Ypos)
Xpos += 35
yPos += 35
Thanks for helping
Don't use a complex key for the dictionary, it makes the code more complex without adding any benefit.
Since you're creating a grid, use row and column rather than i and j. This will make your code easier to understand. Also, don't use place if you're creating a grid. Tkinter has a geometry manager specifically for creating a grid.
Since you're creating a text widget with a height of one line, it makes more sense to use an entry widget.
Here's an example:
import Tkinter as tk
root = tk.Tk()
d = {}
window = tk.Frame(root, borderwidth=2, relief="groove")
window.pack(fill="both", expand=True)
for row in range(9):
for column in range(9):
entry = tk.Entry(window, width=1, relief="flat", font=("Calibri",16))
entry.grid(row=row, column=column, sticky="nsew")
d[(row,column)] = entry
root.mainloop()
Whenever you need to access the data in a cell, you can use the row and column easily:
value = d[(3,4)].get()
print("row 3, column 4 = %s" % value)

Resizing tkinter listbox to width of largest item, using .grid

I have two listboxes that are side by side. They use the lstBox.grid() method to order them in the window. I then have a dropdown option that changes the items displayed in one of the listboxes. The ultimate aim here is to be able to "add" items from one box to the other, and remove ones from the other. My issue is that I don't know how to expand the list box width to be that of the largest item it contains. I have a method that is used for handling when the dropdown is changed, and determining its value to change the items as appropriate, but te listbox doesn't change width.
I am aware that by using lstBox.pack(fill=X,expand=YES), the listbox will resize, but i'm using the .grid() geometry.
Any suggestions?
You can list all your items to find the biggest (if there aren't too much it should be fine). For instance with strings you count their length with 'len(item)'.
Then, when you create your listbox (not when you grid it) your set its width with 'width = "The size you want" ', if the size you put in there is well defined with regard to the length of the biggest item, you shouldn't have any problem.(I think I remember, the listbox's width's unity is given by the size of the text in it, but it needs to be checked)
I don't know grid that much, so that I don't know if there is any faster option to do it.
It should look something like this:
len_max = 0
list_items = ["item2", "item2", "item3+a few characters for the size"]
for m in list_items:
if len(m) > len_max:
len_max = len(m)
import tkinter
master = Tk()
my_listbox1 = Listbox(master, width = len_max)
my_listbox1.grid(row = 0, column = 0)
my_listbox2 = Listbox(master, width = len_max)
my_listbox2.grid(row = 0, column = 1)
my_listbox1.insert(END, list_items[0])
my_listbox2.insert(END, list_items[1])
my_listbox2.insert(END, list_items[2])
master.mainloop()

Categories

Resources