Right-click blocks in the graph, Document tree, or Libraries tree and choose “Port Options…”. Unified port list with:Add/remove port Name Type (Signal currently) Input/output orientation New ports start at (0, 0) in the icon editor. Connected ports cannot be removed, reoriented, or changed incompatibly. Added a PortType registry; connections require matching port types. Removed/hid the separate Add Input and Add Output workspace tools. Library port changes are written back to the library JSON. Added independent graph and icon grid-size settings. Components, interface terminals, icon shapes, resize handles, and icon ports snap to their corresponding grid. Icon canvases and component hitboxes are now fixed at 128×128. Selected icon shapes show a bottom-right resize handle. Circles preserve equal width and height while resizing. Shapes and ports are constrained to the icon hitbox. Fixed the icon-editor crash and grid behavior. Renamed the resize handle’s shape attribute, which was overriding Qt’s required shape() method. Icon shapes, resize handles, and port anchors now snap while dragging. Graph blocks and interface terminals also snap while dragging. Replaced the nearly invisible dotted graph grid with higher-contrast grid lines. Retained final release-time snapping as a safety check. Python compilation and diff validation pass.
190 lines
7.7 KiB
Markdown
190 lines
7.7 KiB
Markdown
# BEdit Qt starter
|
|
|
|
A small desktop application scaffold using Python and PySide6 (the official Qt
|
|
bindings). Its interface is maintained in Qt Designer and it includes a main
|
|
window, menu bar, blank central workspace, common keyboard shortcuts, and
|
|
persisted window geometry. The application forces Qt's light Fusion palette, so
|
|
it remains light even when the operating-system theme is dark.
|
|
|
|
## Run it
|
|
|
|
Python 3.10 or newer is required. From this directory:
|
|
|
|
```bash
|
|
python -m venv .venv
|
|
```
|
|
|
|
Activate the environment:
|
|
|
|
- Windows PowerShell: `.venv\Scripts\Activate.ps1`
|
|
- Windows Command Prompt: `.venv\Scripts\activate.bat`
|
|
- Linux/macOS: `source .venv/bin/activate`
|
|
|
|
Then install and launch:
|
|
|
|
```bash
|
|
python -m pip install --upgrade pip
|
|
python -m pip install -e ".[dev]"
|
|
python -m bedit
|
|
```
|
|
|
|
After installation, the `bedit` command also launches the application.
|
|
|
|
## Project layout
|
|
|
|
```text
|
|
.
|
|
├── pyproject.toml dependencies, package metadata, and `bedit` command
|
|
├── README.md
|
|
├── ui/main_window.ui editable Qt Designer source
|
|
└── src/bedit
|
|
├── __main__.py supports `python -m bedit`
|
|
├── app.py starts Qt and applies the forced light palette
|
|
├── main_window.py behavior and signal connections
|
|
└── ui_main_window.py generated from the Designer file; do not hand-edit
|
|
```
|
|
|
|
## Designing the UI further
|
|
|
|
The project now uses Qt Designer. It is included with PySide6 on most
|
|
installations. Open the existing form with:
|
|
|
|
```bash
|
|
pyside6-designer ui/main_window.ui
|
|
```
|
|
|
|
In Designer, use the Widget Box to add controls, the Object Inspector to select
|
|
them, and the Property Editor to name and configure them. Always put widgets in
|
|
a layout (horizontal, vertical, grid, or form) so the window resizes correctly.
|
|
|
|
Save the form, close the running application if necessary, then regenerate its
|
|
Python wrapper:
|
|
|
|
```bash
|
|
pyside6-uic ui/main_window.ui -o src/bedit/ui_main_window.py
|
|
```
|
|
|
|
Do not hand-edit the generated Python file; change the `.ui` file and regenerate
|
|
it. Add behavior and signal connections in `main_window.py`. Widget names from
|
|
Designer are available there through `self.ui`, such as `self.ui.graphView`.
|
|
|
|
In VS Code, the same commands are available through **Terminal → Run Task**:
|
|
|
|
- **Qt: Open Main Window in Designer** opens the form for visual editing.
|
|
- **Qt: Build Designer Files** compiles resources and then regenerates the UI
|
|
wrapper. It is the default build task, available with `Ctrl+Shift+B`.
|
|
- The separate resource and UI compilation tasks remain available when only one
|
|
generated file needs rebuilding.
|
|
|
|
## A sensible next design pass
|
|
|
|
1. Sketch the main tasks and screens before choosing widgets.
|
|
2. Turn each major area into its own widget class in `src/bedit/widgets/`.
|
|
3. Use a `QStackedWidget` for page-like navigation, or `QDockWidget` for movable
|
|
tool panels in an editor-style application.
|
|
4. Use reusable `QAction` objects for menu commands and any future toolbars.
|
|
5. Keep file/data operations outside widget classes as the application grows.
|
|
6. Add icons through a Qt resource file (`.qrc`) so packaging is reliable.
|
|
7. Test on Windows regularly; fonts, scaling, and native dialogs vary by platform.
|
|
|
|
## Graph and library prototype
|
|
|
|
Documents and libraries use the same recursive format: a library is simply a
|
|
BEdit document used as a copy source. The built-in example defines A, B, and C.
|
|
|
|
- A document can own multiple independent top-level graph or text components.
|
|
Right-click **Current Document** to create one, and double-click a current
|
|
component in the tree to activate it.
|
|
- Drag a component from Libraries onto the workspace. Placement recursively
|
|
copies it with new IDs, leaving no link to the source.
|
|
- Drag components to move them; movement participates in undo and redo.
|
|
- Components, interface terminals, and connections are selectable. Use a rubber
|
|
band or Ctrl-click for multiple selection, Delete to remove items, and the
|
|
standard Cut/Copy/Paste shortcuts to duplicate selected component groups.
|
|
- Click an output port and then an input port to create a connection.
|
|
- Double-click a graph component to open its owned subgraph; use **Up** to return.
|
|
- Graph components show **Pointer**, **Input**, and **Output** tools. Select an
|
|
interface tool and click the canvas to add a visible internal terminal and a
|
|
corresponding external block port. Interface terminals can be moved afterward.
|
|
- Right-click a component on the canvas or in Current Document to edit its name,
|
|
icon shape, icon text, fill color, and border color. The same dialog can hide
|
|
that component's contained subtree from the Libraries tree.
|
|
- Double-click a text component to edit its input list, output list, and
|
|
`implementation.source` JSON.
|
|
- Right-click any graph component under Current Document to add nested graph or
|
|
text blocks. Any current-document component can also be deleted there.
|
|
- The active document hierarchy has its own Document panel; the Libraries panel
|
|
contains only configured external libraries.
|
|
- Select one or more blocks and press `Ctrl+R`, or use the Transform toolbar, to
|
|
rotate them clockwise by 90 degrees. Rotation is saved and supports undo/redo.
|
|
**Apply JSON** updates that source and participates in undo/redo.
|
|
- File → Save writes the complete recursive document to JSON.
|
|
- File → Close Document removes the active document and returns to an empty
|
|
workspace. An open graph uses a light gray, 32-unit dotted canvas.
|
|
- Edit → Settings → Libraries accepts document files or folders of JSON files.
|
|
|
|
Every component owns its ports, declarative icon, properties, and child graph:
|
|
|
|
```json
|
|
{
|
|
"format": "bedit-document",
|
|
"version": 1,
|
|
"roots": [{
|
|
"id": "my-component",
|
|
"name": "My Component",
|
|
"position": {"x": 0, "y": 0},
|
|
"interface": {
|
|
"inputs": [{"id": "in", "name": "Input", "type": "signal", "properties": {
|
|
"iconPosition": {"x": 0, "y": 40}
|
|
}}],
|
|
"outputs": [{"id": "out", "name": "Output", "type": "signal", "properties": {
|
|
"iconPosition": {"x": 128, "y": 64}
|
|
}}]
|
|
},
|
|
"icon": {
|
|
"size": {"width": 128, "height": 128},
|
|
"elements": [{
|
|
"type": "rectangle", "x": 1, "y": 1,
|
|
"width": 126, "height": 126,
|
|
"cornerRadius": 5,
|
|
"fill": "#dbeafe", "stroke": "#245c9c",
|
|
"lineWidth": 1.5, "lineStyle": "solid"
|
|
}]
|
|
},
|
|
"properties": {},
|
|
"implementation": {
|
|
"kind": "text",
|
|
"source": {
|
|
"equations": ["out = gain * in"],
|
|
"parameters": {"gain": 1.0}
|
|
}
|
|
}
|
|
}]
|
|
}
|
|
```
|
|
|
|
Graph components use `"implementation": {"kind": "graph", "graph": ...}`;
|
|
text components use `"implementation": {"kind": "text", "source": ...}` and
|
|
never own a graph. Vector icons can contain rectangles, circles, ellipses,
|
|
lines, triangles, and text. Each element owns its geometry, fill, stroke, and
|
|
line style; ports keep their icon anchor in `properties.iconPosition`. The
|
|
port type registry controls which types may connect (currently `signal` only).
|
|
Graph and icon grid sizes are configured independently in Settings. The
|
|
recursive model is under `src/bedit/document/`, library loading
|
|
and the live Current Document tree are under `src/bedit/library/`, and graphics
|
|
are isolated under `src/bedit/workspace/`.
|
|
|
|
## Optional tools
|
|
|
|
You do not need another GUI framework. Useful additions are:
|
|
|
|
- **Qt Designer** for drag-and-drop form layout.
|
|
- **Ruff** for formatting/linting (`ruff check .`).
|
|
- **pytest-qt** later for GUI interaction tests.
|
|
- **PyInstaller** or **Nuitka** later to produce a Windows `.exe`.
|
|
|
|
The light colors are defined in `apply_light_theme()` in `src/bedit/app.py`.
|
|
Adjust that palette if you want different light colors. Avoid a large stylesheet
|
|
unless the application needs highly customized controls; palettes preserve more
|
|
of Qt's standard behavior.
|