Skip to main content

A GUI framework built on Pygame. Designed as a retained-mode UI system with a component tree, extensible widgets, and focus management.

Project description

pygame-widget-kit

PyPI

A GUI framework built on Pygame. pygame-widget-kit is a retained-mode UI system with a component tree, event routing, focus and modal management, and extensible widgets such as Select/Dropdown and TextInput with mouse-based text selection and clipboard support.

PyPI: https://pypi.org/project/pygame-widget-kit/

Features

  • Retained-mode component tree with nested children
  • Event routing with hover, focus, and active state handling
  • Modal/dropdown support via UIManager
  • Built-in widgets: Button, Text, Select, Radio, TextInput, Slider,TextArea,TextInput2D
  • Text input filtering modes (text, number, hex, binary, octal)

Installation

pip install pygame-widget-kit

Pygame is listed as a dependency (pygame >= 2.0.0). Make sure you call pygame.init() before creating widgets.

Usage

import pygame
from pygame_widget_kit import *


SCREEN_WIDTH = 900
SCREEN_HEIGHT = 720


def update_label_from_input(input_box: TextInput, label: Text):
    label.set_text(f"Label: {input_box.text_value}")


def update_select_label(select: Select, label: Text):
    label.set_text(f"Selected: {select.selected_value}")


def main():
    pygame.init()
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    clock = pygame.time.Clock()

    root = Widget((0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), border_color=None)
    ui = UIManager(root)

    title = Text("pygame-widget-kit demo", pos=(24, 20), text_color=(0, 0, 0))
    root.add_child(title)

    input_box = TextInput(rect=(24, 70, 220, 36), initial_text="")
    update_button = Button("Update label", pos=(256, 70), size=(160, 36))
    value_label = Text("Label: (empty)", pos=(432, 76), text_color=(0, 0, 0))
    update_button.click_bind(update_label_from_input, input_box, value_label)

    root.add_child(input_box)
    root.add_child(update_button)
    root.add_child(value_label)

    input_types_title = Text("input types:", pos=(24, 150), text_color=(0, 0, 0))
    root.add_child(input_types_title)

    input_rows = [
        ("Allow all:", ALLOW_ALL_CHARS),
        ("Text only:", TEXT_ONLY),
        ("Number only:", NUMBER_ONLY),
        ("Hex only:", HEX_ONLY),
        ("Binary only:", BINARY_ONLY),
    ]

    input_label_x = 24
    input_box_x = 200
    input_row_y = 190
    input_row_gap = 44

    for index, (label_text, mode) in enumerate(input_rows):
        row_y = input_row_y + index * input_row_gap
        row_label = Text(label_text, pos=(input_label_x, row_y + 6), text_color=(0, 0, 0))
        row_input = TextInput(rect=(input_box_x, row_y, 240, 34), allowed_char_mode=mode)
        root.add_child(row_label)
        root.add_child(row_input)

    select_label = Text("Select:", pos=(24, 430), text_color=(0, 0, 0))
    select = Select(
        rect=(100, 424, 160, 32),
        options=["Easy", "Hard", "Expert"],
        default_index=0,
        z_index=2
    )
    select_value = Text("Selected: Easy", pos=(280, 430), text_color=(0, 0, 0))
    select.bind_on_option_chance(update_select_label, select, select_value)

    root.add_child(select_label)
    root.add_child(select)
    root.add_child(select_value)

    radio_label = Text("Radio:", pos=(24, 490), text_color=(0, 0, 0))
    radio = Radio(
        (100, 486, 150, 28),
        options=["OPTION A","OPTION B","OPTION C"],
        default_index=0,
    )
    radio_value = Text("Radio: A", pos=(280, 490), text_color=(0, 0, 0))

    root.add_child(radio_label)
    root.add_child(radio)
    root.add_child(radio_value)

    radio_last_value = radio.get_value()
    slider = Slider((20,580),size=(500,20),min_value=50,max_value=2000)
    slider_value = Text("Sider Value", pos=(20, 600), text_color=(0, 0, 0))
    slider.change_bind(update_slider_label,slider,slider_value)
    
    root.add_child(slider)
    root.add_child(slider_value)

    

    running = True
    while running:
        clock.tick(60)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            ui.handle_event(event)

        current_radio_value = radio.get_value()
        if current_radio_value != radio_last_value:
            radio_value.set_text(f"Radio: {current_radio_value}")
            radio_last_value = current_radio_value

        screen.fill((250, 250, 250))
        root.draw(screen)
        pygame.display.flip()

    pygame.quit()


if __name__ == "__main__":
    main()

Usage notes

  • Use UIManager to handle events and manage focus/active state.
  • Call root.add_child(...) to build a component tree. Child positions are relative to their parent.
  • TextInput handles caret blink in draw, so you only need to call draw each frame.
  • Select uses modal behavior through UIManager; clicks outside the dropdown close it.
  • Select expects options as a list of strings and exposes selected_value.
  • Radio expects options as a list of (label, value) tuples and exposes get_value().

TextInput allowed_char_mode

  • ALLOW_ALL_CHARS
  • TEXT_ONLY
  • NUMBER_ONLY
  • HEX_ONLY
  • BINARY_ONLY
  • OCTAL_ONLY

Creating custom widgets

Subclass UIComponent and override any of the following hooks:

  • draw(surface) for custom rendering
  • handle_event(event) for keyboard/mouse logic
  • on_click(event) for click behavior

License

MIT

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

pygame_widget_kit-0.0.5.tar.gz (16.2 kB view details)

Uploaded Source

Built Distribution

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

pygame_widget_kit-0.0.5-py3-none-any.whl (19.1 kB view details)

Uploaded Python 3

File details

Details for the file pygame_widget_kit-0.0.5.tar.gz.

File metadata

  • Download URL: pygame_widget_kit-0.0.5.tar.gz
  • Upload date:
  • Size: 16.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.12.4

File hashes

Hashes for pygame_widget_kit-0.0.5.tar.gz
Algorithm Hash digest
SHA256 86a14e90ac1414fec55bc52342afb3482531998775b6028f13537b3159604268
MD5 cc166e266b381c0e8a2ede066f753cf8
BLAKE2b-256 40647d7dfb53350eefb1f2d6f0d0624ef8616249492bafc45df935121175e480

See more details on using hashes here.

File details

Details for the file pygame_widget_kit-0.0.5-py3-none-any.whl.

File metadata

File hashes

Hashes for pygame_widget_kit-0.0.5-py3-none-any.whl
Algorithm Hash digest
SHA256 c839ad20be5fe2302af1754ea7214d03512d4fcc76b412292b3585680cb9252e
MD5 52e39ab5b08afe95f0281197aed8a75e
BLAKE2b-256 27111699f3635dfe6cc0411b9fc80506f08c88c338e52dedd8ae460c1759d133

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