TIP 729: Add a tk attribtable command to the core

Login
Bounty program for improvements to Tcl and certain Tcl packages.
 Author:         Csaba Nemethi <csaba.nemethi@t-online.de>
 State:          Final
 Type:           Project
 Tcl-Version:    9.1
 Vote:           Done
 Created:        08-Sep-2025
 Keywords:       attribute, widget, Tk
 Tk-Branch:      cargo
 Vote-Summary:   Accepted 7/0/0
 Votes-For:      HO, APN, KW, MC, SL, AK, RA
 Votes-Against:  none
 Votes-Present:  none

Abstract

This TIP proposes to add a tk attribtable command to the core. This command is designed to create attribute tables, used to query or modify arbitrary attributes of a widget.

Rationale

All the mega-widgets developed by the author (mentry, tablelist, scrollarea, scrollableframe, toggleswitch, etc.) provide subcommands used to query and modify arbitrary data attached to a widget, aka attributes. A similar functionality for Tk core widgets is the subject of TIP 369, which proposes to add a cargo subcommand to most core widgets.

Being that the implementation of TIP 369 would require to modify the widgets themselves and wouldn't cover the case of third-party ones, Emiliano Gavilan has recently implemented a tkcargo package, whose tk::cargotable command (written in C) can create an arbitrary number of "cargo tables", which in turn can carry arbitrary widget data.

All the three approaches mentioned above fulfil an important requirement: they automatically free the memory used by the attributes when the widgets are destroyed. An implementation in pure Tcl code would normally need to bind to the Destroy event and do the necessary cleanup from within the binding script, except when this cleanup is performed automatically by the Tk core function Tk_DestroyWindow. This is, however, not viewed as the way to go. Instead, this (revised) TIP proposes to create the attribute tables using C code inspired by the high-quality implementation of Emiliano's tkcargo package.

Specification

The TIP proposes to add a tk attribtable command to the core, designed to create attribute tables, which are used to query and modify arbitrary attributes of any widget. The proposed implementation is inspired by that of Emiliano's tkcargo package.

The proposed tk attribtable command has the signature

tk attribtable tableName

It creates an attribute table of the name tableName, implemented as a hash table and accessible as a command in the namespace of the calling context if not fully qualified, and returns the fully qualified name of the command just created.

If an attribute table of the given name already exists then it is replaced with the new one and all the attributes of all widgets set using the old table instance will be unset.

REMARK 1: When the tableName command is deleted (via rename tableName "" or by deleting the containing namespace), all the attributes of all widgets set using this command are automatically unset and the underlying hash table is deleted. This will free all the memory used by the table.

REMARK 2: When a widget is destroyed, all of its attributes set by all attribute table commands are automatically unset, which will free all the memory used by the widget's attributes.

The command tableName created by this command has the signature

tableName set|get|unset|clear|exists|names|pathnames args

In the description of the supported forms below, pathName specifies a widget whose attributes are being queried or modified via the tableName command.

tableName set pathName name value ?name value ...?

Sets the specified attributes to the given values. Returns an empty string.

tableName get pathName ?name ?defaultValue??

If name is specified then returns the corresponding attribute value, or an empty string or defaultValue (if given) if no corresponding value exists. Otherwise returns a list consisting of all attribute names and values of the widget pathName.

tableName unset pathName name ?name ...?

Unsets the specified attributes. Returns an empty string.

tableName clear pathName

Unsets all attributes and removes pathName from the list of those widgets that have attributes set via tableName set. Returns an empty string.

tableName exists pathName ?name?

If the optional argument is present then returns 1 if the attribute identified by name exists and 0 otherwise. Without the optional argument the return value is 1 if the widget pathName has at least one attribute set via tableName set and 0 otherwise.

tableName names pathName

Returns a list consisting of all attribute names of the widget pathName.

tableName pathnames

Returns a list consisting of the path names of all widgets that have attributes set via tableName set.

Reference Implementation

A ready-to-use reference implementation can be found in the Tk branch cargo. The tk attribtable command is implemented in the file generic/tkCmds.c. It is briefly described in the file doc/tk.n, and a detailed description can be found in the manual page doc/attribtable.n. The tests are contained in the file tests/attribtable.test.

Copyright

This document has been placed in the public domain.

History