A GUI and object framework for Rust drawing on Qt's signals/slots and property/reflection model — implemented in idiomatic Rust with no native dependencies, no foreign ABI, and no codegen outside proc-macros.
- Object model:
ObjectBase, parent/child trees, named lookup, reflection metadata. - Signals/slots: typed
Signal<Args>, dynamic dispatch viaObject::invoke_method, cross-thread queued connections. - Event loop:
Applicationsingleton (builder viaApplicationBuilder; Object-ified withquitslot), per-threadEventLoop(Object-ified; tickless by default, configurableOption<Duration>tick), queued dispatcher. - Timers:
Timerobject withAppDriver/PoolDriver/ThreadDriverexecution contexts. - Painting API (
quartzite-paint-api) — 11-methodPaintertrait (rect/line/text/image/path/transform/state),Color,Pen,Brush/BrushKind(solid + 2-stop linear/radial gradient +Custom(peniko::Gradient)escape hatch),Font,Image,Path—no_std-compatible. - Renderer (
quartzite-renderer) —WindowedApplication(multi-window, configurable last-window-quit policy, proxy-basedAppEvent::Exit) +WindowRegistry(per-window event fan-out viaWindowedAppHandler) +VelloPainter(full 11-methodPainterimpl — rect/line/path/image/text via parley+skrifa; transform/clip stack; vello + wgpu + winit) +RenderHarness/RenderHarnessBuilderoffscreen test harness for snapshot testing. - Widgets (
quartzite-widgets) —WidgetBase,WidgetExt, layouts (BoxLayout,GridLayout), and built-in widgets (Label,Button,LineEdit,TextEdit,ScrollArea,Container). - Snapshot / save-restore (
serdefeature) —capture_object/restore_object/capture_tree/restore_treewith JSON and bincode support;Value::Customround-trips viatypetag.
- Style system (
quartzite-style) — declarative styling on top of widgets.
- Not a Qt port or a Qt binding — Qt is design lineage, not API surface.
- No FFI / native dependencies — pure-Rust toolchain.
Early development. Core crates and the widget system are implemented; full painting and theming layers are next.
| Crate | Status |
|---|---|
quartzite (facade) |
✅ implemented |
quartzite-core |
✅ implemented |
quartzite-macros |
✅ implemented |
quartzite-runtime |
✅ implemented (tickless EventLoop + ApplicationBuilder + Object-ification of EventLoop/Application with stop/quit slots #561) |
examples/ |
✅ runnable examples: hello_object, signals_slots, object_tree, timer |
quartzite-geometry / quartzite-events / quartzite-event-types |
✅ implemented |
quartzite-paint-api |
✅ implemented (Color, Pen, Brush/BrushKind incl. LinearGradient/RadialGradient/Custom gradient, Font, Image, Path, 13-method Painter trait; TextCaretCursor/TextVisualLineCursor/TextVisualLine cursor types #317; draw_text_in h_align + v_align: Alignment two-axis extension #555) |
quartzite-paint |
✅ implemented (re-export shell over paint-api + Alignment from geometry + peniko gradient re-exports) |
quartzite-paint-util |
✅ implemented (#410, TranslateGuard RAII wrapper for save/translate/restore triplet; no_std + panic-safe) |
quartzite-renderer |
✅ implemented (WindowedApplication + multi-window WindowRegistry + WindowedAppHandler + VelloPainter full 11-method impl with parley/skrifa text; RenderHarness/RenderHarnessBuilder snapshot harness) |
quartzite-widgets |
✅ implemented (#46) |
quartzite-style-types |
✅ implemented (#47, leaf: Palette, ColorRole; #488 DARK_PALETTE; #402 ColorGroup axis + FocusRing) |
quartzite-style |
✅ implemented (#47, downstream: Style trait, StyleRegistry; #290 DefaultStyle concrete impl; #297 GPU snapshot tests; #318 Container+LineEdit arms; #458 read-only overlay fix; #402 ColorGroup palette migration; #317 StyleClock + caret/selection rendering for TextEdit; #555 design-system conformance audit + Button/Label vertical centring) |
quartzite-style-dispatch |
✅ implemented (#312, widget-tree paint dispatcher: dispatch_paint + WidgetResolver; #393 facade style-dispatch feature; #395 WidgetResolver moved to quartzite-hit-test, re-exported here) |
quartzite-hit-test |
✅ implemented (#395, paint-free reverse-z-order hit_test(root, point, resolver) -> Option<(ObjectId, Point)>; owns the immutable WidgetResolver trait) |
Add quartzite to your Cargo.toml — no sub-crate deps required:
[dependencies]
quartzite = { git = "https://github.com/maratik123/quartzite" }Import the prelude for typical usage, or use explicit module paths:
// one glob covers the object model, signals, derive macros, and runtime
use quartzite::prelude::*;
// explicit paths when you want legibility
use quartzite::core::ObjectBase;
use quartzite::macros::MetaEnum; // requires `derive` feature (on by default)
use quartzite::runtime::Application;Disable the derive feature to skip proc-macro compilation:
quartzite = { git = "...", default-features = false, features = ["std"] }- Rust stable (≥ 1.96)
- Cargo (comes with Rust)
cargo build --workspacecargo test --workspacecargo clippy --workspace --all-targets -- -D warningscargo fmt --all # apply
cargo fmt --all -- --check # verify (CI gate)RUSTDOCFLAGS="-D warnings -D missing-docs" cargo doc --no-deps --workspaceDual-licensed under either of:
- MIT License (https://opensource.org/licenses/MIT)
- Apache License, Version 2.0 (https://www.apache.org/licenses/LICENSE-2.0)
at your option. This is the standard Rust ecosystem dual-license.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual-licensed as above, without any additional terms or conditions.