Hello,
the following script shows a Treeview with names and country codes of
some towns in Germany. Towns with country code "HE" or "BY" should be
shown with coloured background, in the case of "BY" additionally with
white text.
This works using Python 3.5 or 3.6. I seem to remember that it worked
with earlier versions of Python 3.7, but that's not certain. Using
Python 3.7.3 all the entries have white background and black text.
Opening an entry with Enter or double click shows the name of the town
in the Entry field, together with the country name, if the row has the
tag for HE or BY. So the entries have the tags they should, but the
color doesn't change.
Changing the font of an entry using tags does work.
All of these Python versions come with tcl/tk version 8.6, but I don't
know the patch numbers, they probably changed. The official
documentation for tkinter and for tcl/tk seems to show that the script
is correct. I can see no hint of recent changes in the use of tags,
tag_configure and the options usable with tags.
Here is the script:
############################################################################
#!/usr/bin/env python3
# treeview_forum.py
"""Treeview-Komponente erforschen"""
import tkinter as tk
from tkinter import ttk
CITIES = [
"1,Frankfurt,HE",
"2,Augsburg,BY",
"3,Kiel,SH",
"4,Flensburg,SH",
"5,Stuttgart,BW"
]
class TreeFrame(ttk.Frame):
column_defs = {
"#0": {"label": "IDN", "width": 40, "anchor": tk.E},
"Name": {"label": "Name", "minwidth": 200, "stretch": True},
"Country": {"label": "CC", "width": 80}
}
default_width = 100
default_minwidth = 10
default_anchor = tk.W
def __init__(self, parent, export_city, *args, **kwargs):
super().__init__(parent, *args, **kwargs)
self.columnconfigure(0, weight=1)
self.rowconfigure(0, weight=1)
self.export_namecolumn = export_city
self.treeview = ttk.Treeview(self,
columns=["Name", "Country"],
selectmode='browse')
for (name, definition) in self.column_defs.items():
label = definition.get('label', '')
anchor = definition.get('anchor', self.default_anchor)
minwidth = definition.get('minwidth', self.default_minwidth)
width = definition.get('width', self.default_width)
stretch = definition.get('stretch', False)
self.treeview.heading(name, text=label, anchor=anchor)
self.treeview.column(name, anchor=anchor, minwidth=minwidth,
width=width, stretch=stretch)
self.treeview.tag_configure('hessen', background='lightgreen')
self.treeview.tag_configure('bayern', background='darkgray',
foreground='white')
self.treeview.bind('<<TreeviewOpen>>', self.on_open_record)
self.scrollbar = ttk.Scrollbar(self, orient=tk.VERTICAL,
command=self.treeview.yview)
self.treeview.configure(yscrollcommand=self.scrollbar.set)
self.treeview.grid(row=0, column=0, sticky='NSEW')
self.scrollbar.grid(row=0, column=1, sticky='NSW')
def on_open_record(self, *args):
selected_item = self.treeview.selection()[0]
selected_name = self.treeview.set(selected_item, 0)
in_hessen = (" (Hessen)"
if self.treeview.tag_has('hessen', selected_item)
else "")
in_bayern = (" (Bayern)"
if self.treeview.tag_has('bayern', selected_item)
else "")
msg = "{0}{1}{2}".format(selected_name, in_hessen, in_bayern)
self.export_namecolumn(msg)
def populate(self, rows):
"""Clear the treeview & write the supplied data rows to it."""
for row in self.treeview.get_children():
self.treeview.delete(row)
for rec in rows:
idstr = str(rec['ID'])
values = [rec['Name'], rec['CC']]
if rec['CC'] == 'HE':
cc = 'hessen'
elif rec['CC'] == 'BY':
cc = 'bayern'
else:
cc = ''
self.treeview.insert('', 'end', iid=idstr, text=idstr,
values=values, tags=(cc,))
if rows:
self.treeview.focus_set()
first = self.treeview.identify_row(0)
self.treeview.selection_set(first)
self.treeview.focus(first)
class RecordFrame(ttk.Frame):
def __init__(self, parent):
super().__init__(parent)
self.columnconfigure(0, weight=1)
self.rowconfigure(1, weight=1)
ttk.Label(self, text="Ausgewählt:").grid(row=0, column=0)
self.entryvar = tk.StringVar()
ttk.Entry(self, textvariable=self.entryvar).grid(row=1, column=0,
sticky='EW')
def set(self, value):
self.entryvar.set(value)
def get(self):
return self.entryvar.get()
class Application(tk.Tk):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.geometry("360x500")
self.columnconfigure(0, weight=1)
self.rowconfigure(0, weight=1)
self.recordlist = TreeFrame(self, self.show_city)
self.recordlist.grid(row=0, padx=10, pady=10, sticky="NSEW")
self.dataframe = RecordFrame(self)
self.dataframe.grid(row=1, padx=10, pady=10, sticky="NSEW")
self.recordlist.populate(self.get_all_cities(CITIES))
def get_all_cities(self, citynames):
fieldnames = ("ID", "Name", "CC")
allcities = [dict(zip(fieldnames, row.split(','))) for row in
citynames]
return allcities
def show_city(self, city):
self.dataframe.set(city)
root = Application()
root.mainloop()
_______________________________________________
Tkinter-discuss mailing list
Tkinter-discuss@python.org
https://mail.python.org/mailman/listinfo/tkinter-discuss