All notable changes to myTk are documented here.
TabularData._normalize_record()no longer mutatesrequired_fieldson every insertTabularData.record()andupdate_record()now correctly look up records by UUID objects (not just strings)SimpleDialogkey shortcuts (<Return>,<Escape>) now assigned after buttons are created, not before- Several bugs fixed in
entries.py:Entrybinding order,FormattedEntrydisplay initialisation,FormattedEntrycrash on non-numeric input,FormattedEntry.valuesetter coercion,CellEntryfocusout reference,LabelledEntryvalue passthrough NumericEntryconsolidated intoIntEntry;NumericEntrykept as alias for backwards compatibility
formatted_entry_app.pyexample demonstratingFormattedEntrywith various format strings
CanvasView.is_disabledandDialog.is_disablednow propagate disabled/enabled state to all descendant widgets
View.is_disablednow recursively propagates the disabled/enabled state to all descendant widgets (same behaviour asBox)- Refactored
_propagate_disabled()helper fromBoxintoBaseto avoid duplication
Box.is_disablednow recursively propagates the disabled/enabled state to all descendant widgets; disabling aBoxgrays out all contained controls automatically
positionparameter onApp,Window, andDialogfor named screen placement:"center","top-left","top-right","bottom-left","bottom-right"EventCapable._bind_destroy_cancel(): automatically cancels all trackedafter()tasks when a widget is destroyed; called bygrid_into/pack_into/place_intoas a safety net; convention is to also call it at the end ofcreate_widget()overrides_BaseWidget._bind_destroy_cancel(): no-op fallback so subclasses can safely call it regardless of MROApp.__init__binds<Destroy>on root to cancel all pending Tclafter/after_idleevents viaafter info
apply_window_positiondeferred callback no longer causesinvalid command nameerrors when the widget is destroyed before theafter_idlefires
XYPlot.create_widgetwas assigning toself.first_axiswhich is a read-only computed property, causingAttributeErrorviaBindable.__setattr__; fix callsself.figure.add_subplot()directly (same pattern asHistogram)
Histogram.create_widgetnever added a subplot, leavingfirst_axisasNoneand causing a crash inclear_plot()/update_plot()when the histogram was updated (e.g. inMicroscopeApp)
App(no_window=True)now actually withdraws the main window — the parameter was previously accepted but silently ignored- Removed stale
no_window=Truefromenvtest.py; tests need a visible window and the parameter had no effect before this fix
progressbar_app.pyexample demonstrating three ways to update aProgressBar: direct value assignment,step(), and background thread viaschedule_on_main_thread()
bring_to_front=Trueoption onApp— usesosascripton macOS to reliably activate the process window, overcoming editor focus reclaim
ProgressBarandProgressWindowfully implemented and testedProgressBar.step()now updatesvalue_variabledirectly (bypasses unreliablettk.Progressbar.step()sync)ProgressWindowexposesself.progress_barafterrun()- Notification handlers guard against stale observers with
try/exceptaroundwinfo_exists()
Configurablemixin andConfigModelclass for declarative property management with automatic validation and dialog generation (ConfigurableNumericProperty,ConfigurableStringProperty,ConfigurationDialog)
- Mutation-during-iteration bug in
after_cancel_all() Entry.__init__was resetting initial value to empty string- Wildcard re-export and missing
partialimport - Hanging test in
testCustomDialogs - Dead code, hardcoded path, and optional
cv2import - Modernized project structure to current Python packaging standards
schedule_on_main_thread()onAppfor safely dispatching work from background threadsis_main_thread()utility function