diff --git generic/ttk/ttkTheme.c generic/ttk/ttkTheme.c
index 711c4107f8..e13c5842f9 100644
--- generic/ttk/ttkTheme.c
+++ generic/ttk/ttkTheme.c
@@ -405,17 +405,20 @@ typedef struct
 
 static void ThemeChangedProc(void *);	/* Forward */
 
-/* Ttk_StylePkgFree --
- *	Cleanup procedure for StylePackageData.
+/* Ttk_TkDestroyedHandler --
+ *	See bug [310c74ecf440]: idle calls to ThemeChangedProc()
+ *	need to be canceled when Tk is destroyed, since the interp
+ *	may still be active afterward; canceling them from
+ *	Ttk_StylePkgFree() would be too late.
  */
-static void Ttk_StylePkgFree(
+static void Ttk_TkDestroyedHandler(
     ClientData clientData,
-    TCL_UNUSED(Tcl_Interp *))
+    TCL_UNUSED(Tcl_Interp *),
+    TCL_UNUSED(const char *),
+    TCL_UNUSED(const char *),
+    TCL_UNUSED(int))
 {
     StylePackageData *pkgPtr = (StylePackageData *)clientData;
-    Tcl_HashSearch search;
-    Tcl_HashEntry *entryPtr;
-    Cleanup *cleanup;
 
     /*
      * Cancel any pending ThemeChanged calls:
@@ -423,6 +426,19 @@ static void Ttk_StylePkgFree(
     if (pkgPtr->themeChangePending) {
 	Tcl_CancelIdleCall(ThemeChangedProc, pkgPtr);
     }
+}
+
+/* Ttk_StylePkgFree --
+ *	Cleanup procedure for StylePackageData.
+ */
+static void Ttk_StylePkgFree(
+    ClientData clientData,
+    TCL_UNUSED(Tcl_Interp *))
+{
+    StylePackageData *pkgPtr = (StylePackageData *)clientData;
+    Tcl_HashSearch search;
+    Tcl_HashEntry *entryPtr;
+    Cleanup *cleanup;
 
     /*
      * Free themes.
@@ -1728,6 +1744,8 @@ void Ttk_StylePkgInit(Tcl_Interp *interp)
 
     Tcl_SetAssocData(interp, PKG_ASSOC_KEY, Ttk_StylePkgFree, pkgPtr);
 
+    Tcl_TraceCommand(interp, ".", TCL_TRACE_DELETE, Ttk_TkDestroyedHandler, pkgPtr);
+
     /*
      * Create the default system theme:
      *
