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
  • 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.3.tar.gz (14.3 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.3-py3-none-any.whl (16.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: pygame_widget_kit-0.0.3.tar.gz
  • Upload date:
  • Size: 14.3 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.3.tar.gz
Algorithm Hash digest
SHA256 34bdf0dd784a703119dc1f220d861a9c9fd4ef15a5726928e752e94b7b6248bf
MD5 72f34f5b7a7ceeb023a6a7371eba8542
BLAKE2b-256 cff35b41c818987219901ada1cee399c75113362c305cf8a97802dd796fcfb68

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pygame_widget_kit-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 ec1c06963cec9c165494d8154c0dcadcef0b25d81e857080723ba8c97cbdae1c
MD5 f7eee5fbe353db37be8a78a8e6a59278
BLAKE2b-256 b2d08c7505771b26891b7d3d173db2eacaecd8461415b25977df2d7aef471984

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