-
-
Notifications
You must be signed in to change notification settings - Fork 0
Scripts Panel
One floating panel listing every
.pyfile in the active page. Open a window's behavior file, or add a shared library module (helpers.py,api.py, sub-packages) that any behavior file in the same page can import.
| How | Notes |
|---|---|
F6 |
Keyboard shortcut |
| View → Scripts | Menu toggle |
| Scripts button on the workspace strip | Sits to the left of Data at the top of the canvas |
The panel is scoped to the active page. Switching pages refreshes the list. Pages do not share scripts — each page exports as an independent .py, so a project-wide layer would break the per-page export.
| Kind | Visual | Origin | Actions |
|---|---|---|---|
| Behavior file | Orange color + (window) suffix |
Auto-created when you add a window | Open in editor only — rename / delete go through the window chrome |
| Library script | Default color | You add it from the panel toolbar | Open in editor, Rename, Delete, Drag into folders |
| Sub-folder | Light blue | Created from this panel (or the Assets Panel) | Drag files into it, drag the folder itself between parents |
The panel has two columns:
| Column | What it shows |
|---|---|
| Name (tree) | The file / folder structure |
| Attached to | For library scripts: the comma-separated list of windows that have this module attached (see Attached column below). For behavior files: the window name. Empty for folders and un-attached library scripts. |
| Element | Action |
|---|---|
| + Add script | Prompt for a name (helpers.py, services/auth.py, …). Creates the file plus any missing parent folders + __init__.py chain. |
| + Add folder | Prompt for a folder name. Creates the sub-folder with an empty __init__.py so library imports resolve. |
The panel auto-refreshes whenever it regains focus, so files you create, rename, or delete in an external editor (VS Code, Notepad++, file explorer, …) appear as soon as you click back into CTkMaker. No manual refresh button. It also auto-refreshes on attach / detach via the document_attached_scripts_changed event so the Attached column stays in sync.
| Row | Menu |
|---|---|
| Library script | Open in editor • Rename… • Delete |
| Behavior file | Open in editor only |
| Sub-folder | Rename… • Delete (drops to recycle bin, including contents) |
Double-click or Enter — opens in your configured editor (Settings → Editor). Same chain as Event Handlers uses: VS Code → Notepad++ → IDLE fallback.
Delete sends the file to the OS recycle bin (Send2Trash) — recoverable.
A library script becomes attached to a window when you mark it as available to that window's Event Handlers. Only attached modules show up in the event target picker's Library category, and only attached modules export with a matching from . import <module> line.
Two ways to attach / detach:
| How | Where |
|---|---|
| Click the Attached cell on a library row | Opens a window picker — toggle each window on or off, multiple allowed. |
| Drag a script onto a window row (when shown via the Window's Properties panel Attached Scripts group) | Attaches that one script to that one window. |
A library script with zero attachments is still importable by hand-edited code, but the event picker won't list it. Behavior files have no Attached cell — they're always paired with their single window.
Library scripts and sub-folders are draggable inside the tree:
-
Script → folder — moves the file into that folder. Path-as-identity rule applies: every event binding that pointed at the script's old path is invalidated and needs re-picking. The Attached column also clears, because the old
rel_pathreference no longer matches. - Folder → folder — moves the whole sub-package. Same path-as-identity caveat for every script inside it.
- Drag onto empty area or root — moves to the page-root.
A green highlight on the drop-target row confirms where the release will land. Drag is opt-in past a 5-pixel threshold so accidental clicks don't trigger moves.
Behavior files are not draggable — they're locked to the per-window slug. Rename the window if you need to rename the file.
A library script is any .py file in the page's scripts folder whose name does NOT match a window's behavior file slug. Use them for shared helpers across the windows on a single page.
<project>/assets/scripts/<page>/
├── <window>.py Behavior file — auto-managed
├── helpers.py Library script — manual
├── api.py Library script — manual
└── services/
├── __init__.py
└── auth.py Library script in a sub-package
From any behavior file in the same page:
from . import helpers
from .services import auth
class LoginPage:
def on_submit(self):
if helpers.validate_email(self.email_entry.get()):
auth.sign_in(...)Survives export — when you export the page, the whole assets/scripts/<page>/ folder is copied next to the output .py, so the same relative import resolves at runtime.
Variables follow the same rule: Global = page-scope, not project-scope. Each page exports independently, so cross-page sharing would force every page to carry the same code at runtime. If two pages need the same helper today, copy it into each page.
- Naming a library file the same as a window slug (
login.pywhen a window is namedLogin) is rejected — it would shadow the behavior file. - The
+ Add scriptprompt accepts paths (services/auth.py) — sub-folders are created automatically with empty__init__.pyfiles so the import resolves. - A library script is a normal
.py— no decorator, no registration, no contract. Just functions, classes, constants. Behavior files import them like any other Python module.
See also — Event Handlers · Assets Panel · Exporting Code · Variables · Settings