Repository navigation
Comparison with dhxpyt
dhxpyt wraps the
commercial DHTMLX Suite (0.9.18 is the release pyTincture 1.0 locks; 0.9.19 adds
ContextMenu). wapyt is a from-scratch, MIT-licensed widgetset with a
different, smaller API. This page maps every dhxpyt module to its wapyt
counterpart. Gaps feed the Roadmap.
Key: ✅ equivalent · 🟡 partial · 🔷 different shape · ❌ missing · ⭐ wapyt only, or well beyond dhxpyt
- 🟡 Partial: wapyt has the same kind of thing, but specific options, methods or events are missing. Closing the gap means adding those features to the existing widget; each one is listed under Gaps by row.
- 🔷 Different shape: wapyt meets the need through a different kind of thing: a form field instead of a standalone widget, the browser's native control, another wapyt widget, or app CSS. More options will not close it; the question is whether wapyt should also offer the dhxpyt shape.
- A row can be both (🟡🔷).
Reviewed against dhxpyt's configs, wrappers and events on 2026-10-06, and the ✅ rows re-checked on 2026-10-08 (Tree and Toolbar moved to 🟡). Gaps chosen for building are on the Roadmap.
| dhxpyt | wapyt | Status | Notes |
|---|---|---|---|
layout (Layout, MainWindow) |
Layout, MainWindow
|
✅ | Same idea and add_* helpers. Resizable cells with keyboard-accessible splitters; cells collapse, hide and show. wapyt needs APP_ENTRYPOINT because pyTincture only auto-detects dhxpyt's MainWindow. |
grid |
DataTable |
🟡 | Sort, filter, single/multi selection, context menu, resizable/reorderable columns, drop upload, inline cell editing (text, number, select, checkbox, date), frozen leading columns, CSV export with a formula-injection guard. No row spans or footer rows. |
tree |
Tree |
🟡 | Filter box, context menus by node kind and flags, persisted expansion, checkboxes (cascading), drag-and-drop, keyboard and screen-reader support. No inline rename. |
form |
Form |
✅ | Every dhxpyt control (file and avatar fields, toggle groups, static text, two-thumb range included), buttons anywhere, fieldsets and spacers, labels on top or on the left, Python validators (sync or async), focus events, set_properties, whole-form disable and hide. Not copied: posting from the form itself, before* vetoes, on_keydown, a form title. See the field table below. |
tabbar (Tabbar) |
TabWidget |
✅ | Badges, closable and disabled tabs, keep-alive panels. Mount with container=tabs.get_cell(id), not tabbar.add_*. |
sidebar |
Sidebar |
✅ | Icons, badges, nested groups (a flyout when collapsed), headings, separators, spacers, keyboard navigation; see Sidebar. |
window |
Window, ModalWindow
|
✅ |
Window: movable, resizable, non-modal or modal, maximise, position and size from code, footer, stacking, keyboard. ModalWindow stays as the simple centred dialog. |
chat |
Chat |
✅⭐ | wapyt's is much larger: multiple chats with persistence, model picker, artifact panel, push-to-talk and hands-free voice capture. |
cardpanel |
CardPanel |
✅ | Searchable card grid with templates. |
toolbar |
Toolbar |
🟡 | Buttons, toggles, one-of-several groups, dropdown and split buttons, text, badges, an icon-only compact mode; see Toolbar. No search input, date picker or loading state. |
menu, ContextMenu (0.9.19) |
ContextMenu, MenuBar
|
🟡 | Right-click menus and a menu bar, with submenus, checked and radio items and persistent item state; see MenuBar. No badge counts or item HTML. |
message (alert/confirm/toast) |
message |
✅ | Toasts plus awaitable alert / confirm / prompt; see Message. |
pagination |
Pagination |
✅ | Page box or numbered buttons, page sizes, summary, unknown totals; see Pagination. |
popup |
Popup, tooltip
|
✅ | Anchored popover plus styled tooltips across the widgets; see Popup. |
calendar |
Form date field, Scheduler
|
🟡🔷⭐ | The date field is the browser's picker; Scheduler goes well beyond dhxpyt's picker-only calendar: day / week / month / agenda views with drag-and-drop appointments. Still no standalone inline date picker with ranges or disabled days. |
timepicker |
Form time field |
🔷 | The browser's time field, as a form field only. |
colorpicker |
Form color field |
🔷 | The browser's colour field, as a form field only. No palettes or transparency. |
combobox |
Form combo field |
🟡🔷 | Search as you type, multi-select chips and custom values, as a form field only. |
listbox |
Listbox |
✅⭐ | Rich items from fields or an escaped template, live widgets inside items, actions, selection, filter, pointer and keyboard drag-and-drop between lists; see Listbox. No virtual list yet. |
slider |
Form range field |
🟡🔷 | One thumb (native) or two (range=True), tick marks and labels, a value readout; as a form field only. |
chart |
Chart |
✅ | Chart on Chart.js: line, area, bar, pie, doughnut, polar area, scatter, bubble, radar; fills and follows resizable containers; one value axis by design. |
kanban |
Kanban |
✅⭐ | Listbox columns: cards with templates and live widgets, pointer and keyboard moves, WIP limits, add-card, collapsible and reorderable columns; see Kanban. No swimlanes yet. |
ribbon |
— | ❌ | Not planned: Toolbar with groups and dropdowns covers the need. |
cardflow |
CardPanel, ResourceBoard
|
🔷 | A searchable card grid and a master/detail board cover the card-list cases; no sortable, groupable, expand-in-place row cards. |
theme (module) |
MainWindow.set_theme, --wapyt-* tokens |
🟡🔷 | Light/dark via data-wapyt-theme; font via --wapyt-font-family. |
gpu (WebGPU helper) |
— | ❌ | Not planned: not a widget. |
| — | Terminal |
⭐ | xterm.js + WebSocket relay. |
| — | ResourceBoard |
⭐ | Master/detail browser. |
| — | filetransfer |
⭐ | Native pickers and streaming transfers. |
| — | ProgressBar |
⭐ | Progress bars and static progress_html; dhxpyt has none. |
| — | MediaPlayer |
⭐ | Video and audio with a queue, a docked music bar, HLS, subtitles and OS media keys; dhxpyt has no media player. See MediaPlayer. |
| dhxpyt form control | wapyt FieldConfig(type=...)
|
|---|---|
InputConfig |
✅ text, password, email, number, url, hidden
|
TextareaConfig |
✅ textarea
|
SelectConfig |
✅ select
|
CheckboxConfig |
✅ checkbox
|
ButtonConfig |
✅ FormButton among the fields or in the action row: on_click, icon, variants (incl. link), full, loading spinner, submit=True. No url (the app navigates in on_click) |
FieldsetConfig, SpacerConfig
|
✅ FormFieldset (titled, own grid, nests, hides / disables as a unit) and FormSpacer
|
ContainerConfig |
🔷 put the widget next to the form |
TextConfig |
✅ type="static", returned by get_values
|
ComboConfig |
🟡 combo (multiple, allow_custom, icon, disabled options); no item template, select-all or virtual list |
CheckboxGroupConfig |
✅ checkbox_group (per-option disabled) |
RadioGroupConfig |
✅ radio
|
ToggleConfig |
🔷 toggle is a switch; dhxpyt's is a pressable button with on/off text and icons |
ToggleGroupConfig |
✅ toggle_group (one choice or multiple, icons, disabled options) |
DatepickerConfig |
🔷 date, datetime-local (native picker); see the calendar gaps |
TimepickerConfig |
🔷 time (native picker) |
ColorpickerConfig |
🔷 color (native picker) |
SliderConfig |
🟡🔷 range, two-thumb range=True, ticks / major_ticks / tick_labels; no vertical slider or custom tick text |
AvatarConfig |
✅ avatar (preview, Remove, start from a URL); uploads go through filetransfer
|
SimpleVaultConfig (file upload) |
✅ file (drop zone, file list, accept / max_size / max_files, required); the upload itself is adopt_files + filetransfer.upload, not target / autosend
|
What each 🟡 / 🔷 row lacks, most useful first. Pure DHTMLX plumbing (css,
paint, destructor and similar) is left out.
-
No veto events. dhxpyt's
before*events (beforeChange,beforeHide,beforeEditEnd…) can cancel an action. wapyt lets the action happen and lets the app put it back (set_cell+set_cell_error,Pagination.set_total), which suits a BFF that has the final say. This is wapyt's shape, not a gap per widget. - Native controls. The date, time, colour and range fields use the browser's own control: mobile pickers, accessibility and locale formats come free, but nothing inside the picker can be changed (ranges, disabled days, palettes). Those need a custom widget, likely in a Popup, as the two-thumb range did (it is wapyt's own slider, not a native input).
Since the review: hidden columns and row/cell classes shipped in #42.
A filter per column header · scroll_to(row, column) · row drag-and-drop · cell templates
and column format · hide_row / show_row · row spans · footer rows and
top/bottom/right splits · per-cell click and hover events · rowHeight,
autoHeight · fit-to-content column widths · xlsx / pdf / png export.
Since the review: clear() and reset() shipped in #43; buttons and
labels on the left (labelPosition, labelWidth, hiddenLabel) in #53;
fieldsets, spacers and static text in #54; validation
callables and successMessage in #55 (a Python function, run in the
browser); focus and blur events and set_focus in #56; on 2026-10-08
set_properties (#57), whole-form disable / hide (#58), maxlength,
field icons and per-option disabled (#59), async validators (#60), file and
avatar fields (#61) and toggle groups (#62). That closes every control
and the methods apps use, so the row is ✅.
Left out on purpose or not yet asked for: on_keydown · preMessage · a form
title and padding · nested rows / cols inside a row · posting from the
form itself (send, target, autosend; wapyt's shape is on_submit or
adopt_files → the app calls the BFF) · before* vetoes.
Since the review: dropdown menus (dhxpyt's MenuItemConfig with items)
shipped as dropdown and split buttons in #50, and the row moved from
✅ to 🟡 on a 2026-10-08 re-check against dhxpyt's configs.
An InputConfig search box in the bar · a DatePickerConfig button · a
loading spinner state on buttons · hotkey bindings · image buttons and
custom HTML items (wapyt keeps markup out of the toolbar on purpose).
Moved from ✅ on the 2026-10-08 re-check: the row's own note listed missing
features. Since then: checkboxes (checkbox, check_item, get_checked,
cascading or not) and drag-and-drop (dragMode, dropBehaviour, with
per-node draggable / droppable) shipped in #63, together with keyboard and
screen-reader support dhxpyt's wrapper did not have.
Still missing: inline rename (editable, edit_item) · item templates ·
dragCopy (copy instead of move) · dragging between two trees.
Since the review: ModalWindow got show / hide / close events in
#41, and a separate Window in #64 covers the rest:
movable, resizable with minimum and maximum sizes, non-modal (or modal),
left / top and set_position, set_size, maximise, and a footer.
Since the review: the menu bar, persistent enable / disable / show / hide and
checked items shipped in #44.
Still missing: badge counts · placement relative to an element (show_at
takes coordinates) · item HTML.
Date ranges and linked calendars · disabled_dates (any rule, not just
min/max) · highlighted days (mark) · an inline, always-visible calendar ·
week numbers · month and year selection modes · the display format and week
start (the browser decides). The large version shipped as the
Scheduler in #67 (its mini month is not yet a standalone picker).
An apply/close step with its events · a fixed 12/24h format (the locale decides) · an inline panel.
Swatch palettes · transparency (alpha) · saved custom colours · grey shades · an inline panel. The native dialog differs by browser and cannot be styled.
Standalone use outside a Form · rich option rows (template) · a custom
filter function · server search while typing (on_input) · virtual
scrolling for big lists · a select-all button · a "3 selected" summary ·
adding a typed value to the options (add_option).
Since the review: two-thumb ranges and tick marks with labels shipped in #49.
Vertical · inverse · a change event when the drag ends · custom tick text · standalone use outside a Form.
Since the review: a real Listbox shipped in #45 with
drag-and-drop, templates and widgets inside items, beyond dhxpyt's. Still
missing: virtual scrolling for very long lists.
A list of row cards with columns, sorting and grouping, that expand in place to show an embedded widget, with per-row colours and in-place updates.
Setting colour variables from Python (dhxpyt's css_vars) · named themes
beyond light and dark · prefers-color-scheme · Chat, CardPanel and
ResourceBoard still use their own colours.
Since the review: the file field shipped in #61: drop zone, file list
with remove buttons, accept / max_size / max_files, required files and
metadata in get_values. The transfer stays with filetransfer (picking,
progress, CSRF) through form.adopt_files.
- Replace
from dhxpyt.layout import MainWindowwithfrom wapyt import MainWindow, addAPP_ENTRYPOINT, and switchwidget.pytowapytand the wapyt version you use (see Getting Started). -
Grid→DataTable:GridConfig(columns=[GridColumnConfig(...)], data=...)becomesDataTableConfig(columns=[ColumnConfig(...)], rows=...), withid_fieldnaming the row key. -
Tabbar.add_grid(id, ...)→DataTable(cfg, container=tabs.get_cell(id)). - Toolbar and sidebar handlers received
(id, event)in dhxpyt; wapyt handlers receive one payload dict (see Events and Async). - Icons carry over: wapyt accepts dhxpyt's
"mdi mdi-pencil"as well as"mdi-pencil", and maps Material Symbols names onto MDI.
wapyt is MIT-licensed · Repository · pyTincture · Issues
Getting started
Widgets
- Layout and MainWindow
- Tree
- DataTable
- Form
- ModalWindow
- Window
- TabWidget
- Toolbar
- Sidebar
- Chat
- Terminal
- CardPanel
- ResourceBoard
- File Transfer
- Message
- ContextMenu
- MenuBar
- Listbox
- Kanban
- ProgressBar
- Pagination
- Popup and tooltips
- Chart
- Scheduler
- MediaPlayer
Guides
Planning
Contributing