Skip to main content

pudu-ui

UI library and framework for creating games and desktop apps with Python and based in pyglet.

The design is retained mode with an imperative paradigm, allowing for complex and performant applications, and widgets with different states that use an Object-Oriented Programming approach.

The components use GLSL shaders for rendering, allowing pixel level control of their look.

It doesn't use native OS controls. That means that your apps would look the same regardless of the platform.

It has different components available:

Components

  • Button
  • Dropdown
  • Frame
  • GridLayout
  • Image
  • ImageButton
  • Label
  • ListLayout
  • PopUp
  • ProgressBar
  • Slider
  • Toggle

Examples

There are many examples using the UI components that you can find in the examples folder.

You can run them like this:

uv run examples/hello_screen.py

Hello World

Here's the hello screen example:

from pudu_ui import App, Label, LabelParams
import pudu_ui


app = App(background_color=pudu_ui.colors.WHITE)


if __name__ == '__main__':
    # Regular text
    params = LabelParams(x=50, y=200, text="Hello World")
    label = Label(params, batch=app.batch)

    # Text anchored right
    fs = pudu_ui.styles.fonts.p2()
    fs.color = pudu_ui.colors.GRAY
    params = LabelParams(
        x=200, y=150, text="Trying something", anchor_x='right', style=fs
    )
    l2 = Label(params, batch=app.batch)

    # Centered text
    fs = pudu_ui.styles.fonts.p3()
    params = LabelParams(
        x=(50 + 150 // 2), y=100, text="Centered text", anchor_x='center',
        anchor_y='center', style=fs
    )
    l3 = Label(params, batch=app.batch)

    app.run()

Params and Style

To avoid having too many parameters on the constructors of component classes we use the Params class, which is a dataclass that stores all parameters for a Widget. Specific components have their own Params class, in this case LabelParams that inherits from Params attributes like x, y, width, height, etc. but also define new attributes like text, anchor_x, anchor_y and style.

# widget.py

@dataclass
class Params:
    x: float = 0.0
    y: float = 0.0
    width: int = 100
    height: int = 100
    focusable: bool = True
    visible: bool = True
    debug_label_color: Color = field(default_factory=default_debug_label_color)
# label.py

@dataclass
class LabelParams(Params):
    text: str = ""
    anchor_x: Literal['left', 'center', 'right'] = 'left'
    anchor_y: Literal['top', 'bottom', 'center', 'baseline'] = 'baseline'
    multiline: bool = False
    resize_type: LabelResizeType = LabelResizeType.NONE
    rotation: float = 0.0
    style: FontStyle = field(default_factory=styles.fonts.p1)

We also define specific Style dataclasses for each component that needs styling. With the objective of separating that data and being able to reuse it. This way we don't end up with a Label constructor that has 20+ parameters.

# styles/fonts.py

@dataclass
class FontStyle:
    font_size: Union[float, int, str] = DEFAULT_FONT_SIZE
    font_name: str = DEFAULT_FONT_NAME
    weight: str = 'normal'
    italic: bool = False
    color: Color  = field(default_factory=default_font_color)
    opacity: int = 255

Widgets can also be given a pyglet Batch so that they are attached to them and drawn with them later. You can also use Group for rendering order. And they can have parents so their position is relative to them.

Example game

I made a small puzzle game that uses pudu-ui and is free and open-source. It's a good example of how you can use this library:

https://github.com/sombra-studio/10-de-10

example game

MVC Framework

With the idea of separating the logic from the view we provide the Controller and Screen classes.

For a given screen in your app, you should write most of the logic in a custom controller class that inherits from Controller. That one is responsible for creating the screen and populating it with data, and that should be done in the on_load method.

You should implement a custom screen class that inherits from Screen that creates all of its widgets and populates them with the data given on the screen's _init_ method.

Objective

  • To be used in games and apps made at Sombra Studio
  • To be cross-platform
  • To be simple
  • To work well in complex applications

Limitations

  • For now, it assumes a fixed resolution screen. That means that it's not responsive, if you change the width and height of the Window the widgets inside don't change

Testing

To run them:

python -m unittest -v tests

This will run every test in the "tests" module, if you add new tests make sure to import them into the "__init__.py" file of the "tests" folder.

Dependencies

  • pyglet

You can install the dependencies by running:

uv sync

or

python -m pip install -r requirements.txt

Metadata

Release files for pudu-ui 0.2.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pudu-ui 0.2.4
File Size Uploaded
pudu_ui-0.2.4.tar.gz 90.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pudu-ui 0.2.4
File Interpreter ABI Platform
pudu_ui-0.2.4-py3-none-any.whl Python 3 none any Details

Total release size: 195.2 kB

Release files / pudu_ui-0.2.4.tar.gz

Download URL pudu_ui-0.2.4.tar.gz
Size 90.8 kB
Tags Source
SHA-256 checksum
How to use checksums
91fc950da32bdb6f54cda65b982124aaa3771be0988ea9953c213f23ee55e794
BLAKE2b-256 checksum
How to use checksums
380be0af2e02377087ddd7dd69cb2aff80f438e4cf3feedc6707268022435172
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.9 {"installer":{"name":"uv","version":"0.9.9"},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / pudu_ui-0.2.4-py3-none-any.whl

Download URL pudu_ui-0.2.4-py3-none-any.whl
Size 104.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
59c0ef6113fc5aa1b655687b3bb42592f59d5c5beb0dedecb7fa5c60e495294d
BLAKE2b-256 checksum
How to use checksums
9e8acb9270b892baedd5454c5c97f40cae9e1ddb95f09fc73d3dbb59df76fb1b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.9 {"installer":{"name":"uv","version":"0.9.9"},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.2.4 This release

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page