I'm creating a Tkinter-based GUI in Python, and I can't find out how to change the height of only one row.
I've tried this code, but it changes height of every row.
from tkinter import *
from tkinter.ttk import *
root = Tk()
Style(root).configure("Treeview", rowheight=40)
tree = Treeview(root, style="Treeview")
tree.pack()
for i in range(100):
tree.insert("", END, i, text=str(i) * i)
root.mainloop()
I've also tried to use the style for certain tags, but it doesn't work.
How can I do what I need?
How to change height of only one row in a Treeview?
I don't think you can change the height of a single row. The treeview was designed to have uniform rows.
Related
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()
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 am learning Python and I want to display buttons in a grid. The below code produces exactly what I want, but the code for displaying the buttons by incrementing x and y does not seem very Pythonic. (I come from a procedural language background) Is there a better way? Thanks for any help.
from tkinter import *
from tkinter import ttk
root = Tk()
numberButtonsFrame = ttk.Frame(root)
numberButtonsFrame.pack()
button=[0]
for i in range(1,10):
button.append (ttk.Button(numberButtonsFrame, text = i))
x=0
y=0
for i in range(1,10):
button[i].grid(row=x,column=y)
y=y+1
if y>2:
x=x+1
y=0
root.mainloop()
When you're dealing with a grid, the solution is very often to use nested loops:
for row in in range(nrows):
for col in range(ncolumns):
buttons[row][col].grid(row=row, column=col) # You could also calculate a linear index if that's what you want
Single loop
As I noted in a comment (along with another poster), there is a way of calculating the row and column based on i (and vice versa).
row, col = divmod(i, ncolumns)
You could do this at the same time as you create each button. You could also simplify the button creation with a list comprehension.
buttons = [ttk.Button(numberButtonsFrame, text = i) for i in range(1,10)]
I assume you added the 0 at the start of your button(s) list to shift the indices: you don't have to do that. Just add 1 to i in your calculations instead.
Lastly, I would recommend using well-named variables rather than literals (eg. ncolumns). And buttonsinstead of button for the list. I'll conclude with an example (// is floor division - the div in divmod):
for i, button in enumerate(buttons):
button.grid(row=i//ncolumns, column=i%ncolumns)
Use the divmod() function to calculate each row and column from the index.
buttons_per_row = 3
for i in range(9):
button = ttk.Button(numberButtonsFrame, text = i+1)
row, col = divmod(i, buttons_per_row)
button.grid(row=row, column=col)
A different method...
Using two nested loops like others have done, you can calculate the text from the row and column simply by:
(r * 3) + c + 1
Obviously, this will return an int so str() will have to be applied -leading to a more succinct solution of:
from tkinter import *
from tkinter import ttk
root = Tk()
numberButtonsFrame = ttk.Frame(root)
numberButtonsFrame.pack()
for r in range(3):
for c in range(3):
ttk.Button(numberButtonsFrame, text=(r * 3) + c + 1).grid(row=r, column=c)
root.mainloop()
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)
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()