Skip to main content

Improved tkinter-style gui system.

Project description

NebulaTk

NebulaTk is an early-stage, Tkinter-style GUI toolkit with a custom widget/rendering pipeline. Widgets are composed into Pillow images and displayed through an OpenGL window backend.

Questions, bug reports, and feature requests: ctrl.alt.op@gmail.com or through this GitHub repo

Current status

  • Project is in active early development.
  • The current Window() path in this branch supports render_mode="image_gl" only, but might be expanded for vulkan later.
  • Rendering currently depends on a GLFW + PyOpenGL backend.

Installation

From the repository root:

pip install -e .

For development and tests:

pip install -r requirements.txt

Quick start

import nebulatk as ntk

window = ntk.Window(title="NebulaTk")
ntk.Button(window, text="Hello NebulaTk").place(20, 20)

You can also run included examples:

python examples/example.py
python examples/relativeplace.py
python examples/word_collage.py
python examples/defaults_theme_toggle.py

Note: example scripts may reference local assets under examples/Images/. If those assets are missing in your checkout, update image paths or provide your own files.

Defaults, themes, and styles

NebulaTk supports file-backed defaults through nebulatk/defaults.py. This lets you:

  • Define app-wide default colors/fonts in a Python module.
  • Define named reusable styles (for example button_1, button_2).
  • Inherit styles from other styles with extends.
  • Switch defaults at runtime and update all widgets that are still default-bound.

1) Create a defaults file

Create a Python file (for example my_defaults_light.py):

DEFAULTS = {
    "default_text_color": "#101010",
    "default_fill": "#ffffff",
    "default_border": "#222222",
    # -1 means "auto size", dynamically recomputed for default-bound widgets
    "default_font": ("Helvetica", -1, "normal"),
    # Used by Window(background_color="default") and by default Window()
    "default_window_background": "#f4f7ff",
}

STYLES = {
    "button_1": {
        "fill": "#d7e8ff",
        "text_color": "#112244",
        "border": "#4477aa",
        "border_width": 2,
    },
    "button_2": {
        "extends": "button_1",
        "fill": "#e9f6d2",
    },
}

You can also use:

  • PROFILE = {"defaults": {...}, "styles": {...}} in one object, or
  • lowercase defaults/styles.

2) Load defaults when creating a window

import nebulatk as ntk

window = ntk.Window(
    title="Themed App",
    defaults_file="my_defaults_light.py",
)

3) Use default-bound widget values

Properties set to "default" (or font=None/font="default") are owned by the defaults system and update when defaults change.

btn = ntk.Button(
    window,
    text="Save",
    fill="default",
    border="default",
    text_color="default",
    font="default",
).place(20, 20)

For image-backed widgets, default fill and default border are transparent by design so image edges are not covered.

4) Apply named styles

Use style references from window.defaults:

primary = ntk.Button(
    window,
    text="Primary",
    style=window.defaults.button_1,
    width=160,
    height=44,
).place(20, 80)

secondary = ntk.Button(
    window,
    text="Secondary",
    style=window.defaults.button_2,
    width=160,
    height=44,
).place(20, 140)

You may also pass a style name string directly:

ntk.Button(window, text="Inline Name", style="button_1").place(200, 80)

5) Override style/default values per widget

If you set a concrete value, that property is no longer default-bound for that widget and will not be changed by later theme switches.

danger = ntk.Button(
    window,
    text="Delete",
    style=window.defaults.button_1,
    fill="#aa0000",  # explicit override
).place(20, 200)

In this example, danger.fill remains #aa0000 after defaults are switched, while other style/default-bound fields still update.

6) Switch themes at runtime

Use window.set_defaults(...) to load a different defaults file:

is_dark = False

def toggle_theme():
    global is_dark
    is_dark = not is_dark
    target = "my_defaults_dark.py" if is_dark else "my_defaults_light.py"
    window.set_defaults(target)

ntk.Button(window, text="Toggle Theme", command=toggle_theme).place(20, 260)

When switched, all widgets that still use default-bound values (including style-bound fields) are updated automatically across the app.

7) Dynamic default font sizing behavior

If a widget is using the default font with size -1, NebulaTk recomputes the font size when widget size/text constraints change (for example resize/reflow). Once you set an explicit font size (for example ("Helvetica", 13, "normal")), that widget stops auto-resizing its font and keeps the explicit size.

Running tests

From the project root:

pytest

Public API highlights

Top-level imports exposed by nebulatk include:

  • Window
  • FileDialog
  • Widgets: Button, Label, Entry, Frame, Slider, Container
  • Utility modules: colors_manager, fonts_manager, image_manager, bounds_manager, standard_methods, animation_controller, rendering, file_manager

Many widget methods are chainable, for example:

ntk.Button(window, text="Chainable").place(10, 10).hide().show()

Project layout

  • nebulatk/ - main package source
  • nebulatk/widgets/ - widget classes and base components
  • examples/ - runnable usage demos
  • tests/ - pytest test suite

Notes

  • This project is not a drop-in implementation of Tk's internal event/render loop.
  • The window/rendering architecture uses both threading and multiprocessing internally.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nebulatk-0.3.6.3.tar.gz (2.0 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nebulatk-0.3.6.3-py3-none-any.whl (85.6 kB view details)

Uploaded Python 3

File details

Details for the file nebulatk-0.3.6.3.tar.gz.

File metadata

  • Download URL: nebulatk-0.3.6.3.tar.gz
  • Upload date:
  • Size: 2.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for nebulatk-0.3.6.3.tar.gz
Algorithm Hash digest
SHA256 d46513c0a711e259f89882e322fb8b1a6a4e2b90f7624f93b666ccf0d0a50655
MD5 906d75f06d267ee15efed2c85a5aeb52
BLAKE2b-256 c0a7d86acc0c0be7313a769f9e64e789f9cccdb1d37881240c0017018fefc453

See more details on using hashes here.

File details

Details for the file nebulatk-0.3.6.3-py3-none-any.whl.

File metadata

  • Download URL: nebulatk-0.3.6.3-py3-none-any.whl
  • Upload date:
  • Size: 85.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for nebulatk-0.3.6.3-py3-none-any.whl
Algorithm Hash digest
SHA256 b9cf5e98c17ab26c49ba8b225d156e85c55e57009729b500e54cc7ae91e0e04a
MD5 019bf4cbd79036ccf12dec4e4fbd6356
BLAKE2b-256 c4e86e7818e9fefb2abb4c2e57e7335d195553d4f8d7f56a12b06f5772d79919

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page