Changing font style of rows in treeview - python

Is it possible to change the font style of the data in rows in treeview?
I've done it for the column headings... not sure how to do it for rows

from tkinter import *
import tkinter.ttk as ttk
root = Tk()
style = ttk.Style()
style.configure("mystyle.Treeview", highlightthickness=0, bd=0, font=('Calibri', 16)) # Modify the font of the body
style.configure("mystyle.Treeview.Heading", font=('Calibri', 16,'bold')) # Modify the font of the headings
style.layout("mystyle.Treeview", [('mystyle.Treeview.treearea', {'sticky': 'nswe'})])
tree = ttk.Treeview(root, style="mystyle.Treeview")
tree.pack()
tree["columns"] = ("one", "two", "three")
tree.column("one", width=150)
tree.column("two", width=150)
tree.column("three", width=150)
tree.heading("one", text="Naar")
tree.heading("two", text="Spoor")
tree.heading("three", text="Vetrektijd")
tree['show'] = 'headings'
tree.insert("", 'end', values=('aboba', 'aboba', 'aboba'))
root.mainloop()

Related

Tkinter Treeview style

Why my table isn't changing style according to what I defined?
I tried using style and map and it didn't change anything.
It seems that the only thing that works is the Theme configuration.
also the scroller isn't show in the Treeview.
from tkinter import *
from tkinter import ttk
class Dashboard:
def __init__(self, filterdDf):
self.filterdDf = filterdDf
root =Tk()
root.title('Dashboard')
root.geometry('1300x690')
root.resizable(False, False)
frame = Frame(root, width=1100, height=690)
frame.configure(background="gray28")
frame.pack(fill=BOTH, expand=True)
rows = len(filterdDf)
tree = ttk.Treeview(root, columns=(1, 2), height=rows, show="headings")
tree.pack(side='left')
tree.place(x=700, y=150)
#Add some style:
style = ttk.Style()
style.theme_use("clam")
style.configure("Treeview",
background="silver",
foreground="black",
rowheight=55,
fieldbackground="silver")
#Change selected color:
style.map("Treeview",
background=[('selected', 'green')])
tree.heading("#0", text="Label", anchor=W)
tree.heading("#1", text="Approach", anchor=CENTER)
tree.heading("#2", text="Recommendation", anchor=CENTER)
tree.column("#0", width=120, minwidth=25)
tree.column("#1", width=300, minwidth=25, anchor=W)
tree.column("#2", width=150, minwidth=25, anchor=CENTER)
scroll = ttk.Scrollbar(frame, orient="vertical", command=tree.yview)
scroll.pack(side='right', fill='y')
tree.configure(yscrollcommand=scroll.set)
for i in range(rows):
tree.insert(parent='', index='end', values=(filterdDf[('Approaches', 'All')].iloc[i],
filterdDf[('Recommendation Level', '')].iloc[i]))
root.mainloop()
This is how my Treeview looks like:
2 columns filled with data.
Thanks!
This is how it suppose to look with the style configuration (diffrent data but same configurations):

tkinter centering two or more widgets

So I created a frame in which I want to put two widgets with them being centered on the x-axis. When it's one object pack() centers it automatically. But I can't figure out two widgets. I tried with grid() but there is free space left on the right which makes it look unsymetrical as seen in the image.
how could I get what is seen on the right? (I'd prefer it being dont with pack() but if there is a solution with grid() and/or place() as well i'd appreciate those as well!)
here's the code for the left picture
from tkinter import *
from tkinter import font
root = Tk()
root.geometry("500x500")
frame = Frame(root, bg="white", highlightbackground="black", highlightthickness=2)
frame.place(relwidth=0.5, relheight=0.5, relx=0.5, rely=0.5, anchor=CENTER)
label = Label(frame, bg="lime", text="label", font=font.Font(size=20))
label.grid(column=0, row=0)
button = Button(frame, bg="yellow", text="pressbutton", font=font.Font(size=20))
button.grid(column=1, row=0)
root.mainloop()
You can use frame.pack() to easily position the frame in the top, middle of its parent.
from tkinter import *
from tkinter import font
root = Tk()
root.geometry("500x500")
frame = Frame(root, bg="white", highlightbackground="black", highlightthickness=2)
frame.pack()
label = Label(frame, bg="lime", text="label", font=font.Font(size=20))
label.grid(column=0, row=0)
button = Button(frame, bg="yellow", text="pressbutton", font=font.Font(size=20))
button.grid(column=1, row=0)
root.mainloop()
You can put the label and button in another frame, and use pack() on that frame:
from tkinter import *
from tkinter import font
root = Tk()
root.geometry("500x500")
frame = Frame(root, bg="white", highlightbackground="black", highlightthickness=2)
frame.place(relwidth=0.5, relheight=0.5, relx=0.5, rely=0.5, anchor=CENTER)
frame2 = Frame(frame)
frame2.pack() # default side='top'
label = Label(frame2, bg="lime", text="label", font=font.Font(size=20))
label.pack(side='left', fill='both')
button = Button(frame2, bg="yellow", text="pressbutton", font=font.Font(size=20))
button.pack(side='left')
root.mainloop()

tkinter : how do I remove all the entries from the treeview and also clear the column names

I am able to delete all the content of the tree view using the code
tree.delete(*tree.get_children())
However the column names remain, and my treeview is pulling different tables so I ideally dont want any column names when rest of the data is deleted. How can I do that?
root = Tk()
root.minsize(width=600, height=700)
#root.resizable(width=0, height=0)
tree = ttk.Treeview(root, selectmode='browse',height='10')
tree.place(x=330, y=45)
vsb = ttk.Scrollbar(root, orient="vertical", command=tree.yview)
vsb.place(x=320, y=45, height=200 + 180)
tree.configure(yscrollcommand=vsb.set)
#frm = Frame(root)
#frm.pack(padx=0, pady=10, anchor='nw')
#frm.pack(side=tk.LEFT,padx=0,pady=10)
#frm.pack(padx=0,pady=10)
tree["columns"] = (1,2)
tree['show'] = 'headings'
tree['height'] = '20'
tree.column(1, width=150, anchor='c')
tree.heading(1, text="Date")
tree.column(2, width=150, anchor='c')
tree.heading(2, text="GT")
def delete_command():
tree.delete(*tree.get_children())
b2 = Button(root, text="delete all", width=12, command=delete_command)
b2.place(x=130, y=45)
root.title('New Data')
root.geometry('650x500')
#root.resizable(False,False)
root.mainloop()
You can change your heading's text = "" by getting all the columns from tree['columns'] and resetting them like so.
def delete_command():
for col in tree['columns']:
tree.heading(col, text='')
tree.delete(*tree.get_children())
But in case you also mean to delete all columns then put tree["columns"] = () line in your delete_command function to clear all the columns.

Seperating two functions using Treeview

I am trying to bind two different functions to two different parts of the treeview. the command deleteItem should only apply to rows, whilst the columnselect function should only apply to columns. When I run this code the second bind overrides the first.
import tkinter as tk
from tkinter import messagebox
from tkinter.font import Font
from tkinter import scrolledtext
from tkinter import ttk
def deleteItem(a):
print("In delete Item")
curItem = AttendanceView.focus()
inter_var = AttendanceView.item(curItem)
ListValues = inter_var['values']
print(ListValues)
def columnnameselect(q):
tk.messagebox.showinfo("","You didn't press a row")
# AttendanceView Specific Table Components
Attendance=tk.Tk()
AttendanceView = ttk.Treeview(Attendance)
AttendanceView["columns"] = ("firstname", "secondname","patrol","present")
AttendanceView.grid(row=3, column=1)
AttendanceView.heading("#0", text="", anchor="w")
AttendanceView.column("#0", anchor="center", width=5, stretch=tk.NO)
AttendanceView.heading("firstname", text="First Name", anchor="w")
AttendanceView.column("firstname", anchor="center", width=80)
AttendanceView.heading("secondname", text="Second Name", anchor="w")
AttendanceView.column("secondname", anchor="center", width=90)
AttendanceView.heading("patrol", text="Patrol", anchor="w")
AttendanceView.column("patrol", anchor="center", width=80)
AttendanceView.heading("present", text="Present", anchor="w")
AttendanceView.column("present", anchor="center", width=80)
AttendanceView.grid(row=3, column=1, columnspan=5)
AttendanceView.bind('<ButtonRelease-1>', deleteItem)
AttendanceView.bind('<ButtonRelease-1>', columnnameselect)
AttendanceViewScrollbar = ttk.Scrollbar(Attendance, orient="vertical", command=AttendanceView.yview)
AttendanceView.configure(yscroll=AttendanceViewScrollbar.set)
AttendanceViewScrollbar.grid(row=3, column=6, sticky="ns")
AttendanceView.insert("", "end", text="", values=(("Ethel",("Kennedy"),("Cow"),(""))))
AttendanceView.insert("", "end", text="", values=(("Jack",("Kennedy"),("Lion"),(""))))
AttendanceView.insert("", "end", text="", values=(("Bobby",("Kennedy"),("Zebra"),(""))))
The desired outcome:
When a column is selected, columnselect is run.
When a row is selected, deleteItem is run.
Any help would be appreciated.

how to place frames in tkinter to display the data in a table?

I need to display the data in a table using frames or grid in tkinter.
I have displayed the data in the tkinter window but i want to place in a table, so can anyone help me with the code (and also the scroll bar)..
here is the code :
def allClub():
data=cursor.execute("SELECT * from CLUBS order by club_name")
master = Tk()
master.geometry('500x500')
master.title('CLUBS')
Label1 = Label(master, text="CLUB ID", width=10)
Label1.grid(row=0, column=0)
Label2 = Label(master, text="CLUB NAME", width=10)
Label2.grid(row=0, column=1)
Label3 = Label(master, text="RATING", width=10)
Label3.grid(row=0, column=2)
Label1 = Label(master, text="MANAGER", width=10)
Label1.grid(row=0, column=3)
Label1 = Label(master, text="CHAIRMAN", width=10)
Label1.grid(row=0, column=4)
Label1 = Label(master, text="LEAGUE", width=15)
Label1.grid(row=0, column=5)
Label1 = Label(master, text="TITLES", width=10)
Label1.grid(row=0, column=6)
Label1 = Label(master, text="YEAR FOUNDED", width=10)
Label1.grid(row=0, column=7)
for index, dat in enumerate(data):
Label(master, text=dat[0]).grid(row=index+1, column=0)
Label(master, text=dat[1]).grid(row=index+1, column=1)
Label(master, text=dat[2]).grid(row=index+1, column=2)
Label(master, text=dat[3]).grid(row=index+1, column=3)
Label(master, text=dat[4]).grid(row=index+1, column=4)
Label(master, text=dat[5]).grid(row=index+1, column=5)
Label(master, text=dat[6]).grid(row=index+1, column=6)
Label(master, text=dat[7]).grid(row=index+1, column=7)
link for screenshot of output window here:
https://i.stack.imgur.com/zFymD.jpg
Tkinter doesn't have any "table" widget and if you are planning to have a lot of rows and columns, the best thing you could use is a Treeview or Listbox.
On the other hand you cant create a scrollbar for Frame because the documentation for that widget doesn't say it supports scrolling. There is a solution for this problem that involves creating a canvas and you can check it out here.
Here is an example of Treeview widget:
from tkinter import *
from tkinter import ttk
root = Tk()
root.geometry("500x200")
data = [ ["val1", "val2", "val3"],
["asd1", "asd2", "asd3"],
["bbb1", "bbb3", "bbb4"],
["ccc1", "ccc3", "ccc4"],
["ddd1", "ddd3", "ddd4"],
["eee1", "eee3", "eee4"] ]
frame = Frame(root)
frame.pack()
tree = ttk.Treeview(frame, columns = (1,2,3), height = 5, show = "headings")
tree.pack(side = 'left')
tree.heading(1, text="Column 1")
tree.heading(2, text="Column 2")
tree.heading(3, text="Column 3")
tree.column(1, width = 100)
tree.column(2, width = 100)
tree.column(3, width = 100)
scroll = ttk.Scrollbar(frame, orient="vertical", command=tree.yview)
scroll.pack(side = 'right', fill = 'y')
tree.configure(yscrollcommand=scroll.set)
for val in data:
tree.insert('', 'end', values = (val[0], val[1], val[2]) )
root.mainloop()
# One way to make a table is to use a loop for the Entry class.
import tkinter as tk
win=tk.Tk()
win.title('Tk GUI')
cols=['Col1','Col2','Col3']
data = [ ["val1", "val2", "val3"],
["asd1", "asd2", "asd3"],
["bbb1", "bbb3", "bbb4"],
["ccc1", "ccc3", "ccc4"],
["ddd1", "ddd3", "ddd4"],
["eee1", "eee3", "eee4"] ]
for y in range(len(data)+1):
for x in range(len(cols)):
if y==0:
e=tk.Entry(font=('Consolas 8 bold'),bg='light blue',justify='center')
e.grid(column=x, row=y)
e.insert(0,cols[x])
else:
e=tk.Entry()
e.grid(column=x, row=y)
e.insert(0,data[y-1][x])
win.mainloop()

Categories