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

Reply via email to