{"id":30067068,"url":"https://github.com/jacobwilliams/qtpyguihelper","last_synced_at":"2025-08-08T08:03:17.740Z","repository":{"id":302926607,"uuid":"1013800979","full_name":"jacobwilliams/qtpyguihelper","owner":"jacobwilliams","description":"A vibe-coded Python library to help create simple GUIs with qtpy/pyside6/pyqt, wxpython, tkinter, GTK3/GTK4 and read/write config data","archived":false,"fork":false,"pushed_at":"2025-08-02T14:11:31.000Z","size":3229,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-08-02T16:21:39.338Z","etag":null,"topics":["gtk","gtk3","gtk4","gui","json","pygobject","pyqt","pyside6","python","qtpy","tkinter","wxpython","wxwidgets"],"latest_commit_sha":null,"homepage":"https://jacobwilliams.github.io/qtpyguihelper/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jacobwilliams.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-04T13:40:18.000Z","updated_at":"2025-08-02T14:11:34.000Z","dependencies_parsed_at":"2025-07-04T20:42:06.401Z","dependency_job_id":null,"html_url":"https://github.com/jacobwilliams/qtpyguihelper","commit_stats":null,"previous_names":["jacobwilliams/qtpyguihelper"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jacobwilliams/qtpyguihelper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jacobwilliams%2Fqtpyguihelper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jacobwilliams%2Fqtpyguihelper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jacobwilliams%2Fqtpyguihelper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jacobwilliams%2Fqtpyguihelper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jacobwilliams","download_url":"https://codeload.github.com/jacobwilliams/qtpyguihelper/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jacobwilliams%2Fqtpyguihelper/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269385801,"owners_count":24408432,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-08T02:00:09.200Z","response_time":72,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gtk","gtk3","gtk4","gui","json","pygobject","pyqt","pyside6","python","qtpy","tkinter","wxpython","wxwidgets"],"created_at":"2025-08-08T08:02:39.211Z","updated_at":"2025-08-08T08:03:17.724Z","avatar_url":"https://github.com/jacobwilliams.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# QtPyGuiHelper\n\nA Python library for creating GUI applications from JSON configuration files. This library allows you to define GUI layouts, widgets, and their properties in JSON format and automatically generate the corresponding interface.\n\n**Multi-Backend Support:**\n- **Qt backend** via qtpy (supports PySide6/PyQt6)\n- **wxPython backend** as a cross-platform alternative\n- **tkinter backend** built into Python (no additional dependencies)\n- **GTK backend** via PyGObject (native Linux desktop integration, GTK3/GTK4 support)\n\nThe library automatically detects available backends and provides a unified interface, allowing you to switch between Qt, wxPython, tkinter, and GTK seamlessly.\n\n## Examples\n\nHere are screenshots of the same dialog generated by the different backends:\n\n### PySide6 backend:\n![Qt Backend](media/qt.png)\n\n### WxPython backend:\n![wxPython Backend](media/wx.png)\n\n### GTK4 backend:\n![gtk4 Backend](media/gtk4.png)\n\n### Tkinter backend:\n![Tkinter Backend](media/tk.png)\n\n## Features\n\n- 🎯 **JSON-Driven**: Define your entire GUI in JSON configuration files\n- 🔀 **Multi-Backend**: Support for Qt (PySide6/PyQt6), wxPython, GTK (GTK3/GTK4), and tkinter backends\n- 🎨 **Multiple Layouts**: Support for vertical, horizontal, grid, and form layouts\n- 🧩 **Rich Widget Set**: Text fields, numbers, dates, checkboxes, radio buttons, file pickers, color pickers, and more\n- ✅ **Form Validation**: Built-in validation for required fields and data types\n- 🎛️ **Customizable**: Extensive configuration options for each widget\n- 📡 **Event Handling**: Built-in callbacks and signals for form submission and field changes\n- 🔧 **Programmatic Control**: Runtime manipulation of form fields and values\n- 🌲 **Nested Fields**: Support for hierarchical data structures using dot notation (e.g., \"global.app_name\")\n- 📑 **Tabbed Interfaces**: Organize fields into tabs for better user experience\n- 💾 **Data Persistence**: Load and save form data with smart defaults and metadata support\n- 🎨 **Custom Buttons**: Add custom buttons with callbacks and styling\n\n## Installation\n\nQtPyGuiHelper supports multiple GUI backends for maximum flexibility and cross-platform compatibility.\n\n### Backend Options\n\n**Qt Backend (Default)**: Uses `qtpy` as an abstraction layer, supporting both PySide6 and PyQt6.\n**wxPython Backend**: Alternative cross-platform GUI toolkit with native look and feel.\n**GTK Backend**: PyGObject is a Python package which provides bindings for GObject based libraries such as GTK.\n**tkinter Backend**: Built into Python, requires no additional dependencies, perfect for simple GUIs.\n\n### Dependency installation\n\nThe preferred way to install all the dependencies is via `conda-forge`. For example, using `pixi`, to build an environment. Here is an example using `pixi` and running all the tests:\n\n```bash\nmkdir env\ncd env\npixi init .\n\npixi add python\npixi add pytest\n### for GTK backend:\npixi add pygobject\npixi add gtk3\n# or pixi add gtk4\n### for Qt/PyQt6 backend:\npixi add pyside6\npixi add qtpy\n### for wxPython backend:\npixi add wxpython\n\npixi install\npixi shell\ncd ..\n./test.sh\n```\n\n### Other installation options:\n\n```bash\ngit clone https://github.com/jacobwilliams/qtpyguihelper.git\ncd qtpyguihelper\npip install -e .        # Install with tkinter Backend (No Extra Dependencies)\n\npip install .[pyside6]  # install with PySide6 Backend\n\npip install .[pyqt6]    # Install with Qt Backend (PyQt6)\n\npip install wxpython\u003e=4.2.0  # Install with wxPython Backend\npip install -e .\n\npip install pygobject\u003e=3.42.0  # Install with GTK Backend\npip install -e .\n# System dependencies for GTK development (Linux)\n# GTK3:\nsudo apt-get install libgtk-3-dev  # Ubuntu/Debian\nsudo dnf install gtk3-devel        # Fedora\n# GTK4:\nsudo apt-get install libgtk-4-dev  # Ubuntu/Debian\nsudo dnf install gtk4-devel        # Fedora\n# macOS (with Homebrew)\nbrew install gtk+3 gtk4 pygobject3\n# Windows: Use MSYS2 or pre-built wheels\n```\n\n## Quick Start\n\n### 1. Create a JSON Configuration File\n\nCreate a JSON file defining your GUI structure:\n\n```json\n{\n  \"window\": {\n    \"title\": \"My Application\",\n    \"width\": 500,\n    \"height\": 400\n  },\n  \"layout\": \"form\",\n  \"fields\": [\n    {\n      \"name\": \"username\",\n      \"type\": \"text\",\n      \"label\": \"Username\",\n      \"required\": true,\n      \"placeholder\": \"Enter username\"\n    },\n    {\n      \"name\": \"email\",\n      \"type\": \"email\",\n      \"label\": \"Email Address\",\n      \"required\": true\n    },\n    {\n      \"name\": \"age\",\n      \"type\": \"number\",\n      \"label\": \"Age\",\n      \"min_value\": 0,\n      \"max_value\": 120\n    },\n    {\n      \"name\": \"subscribe\",\n      \"type\": \"checkbox\",\n      \"label\": \"Subscribe to newsletter\"\n    }\n  ],\n  \"submit_button\": true,\n  \"submit_label\": \"Submit\",\n  \"cancel_button\": true\n}\n```\n\n### 2. Create the GUI Application\n\n```python\nimport sys\nfrom qtpyguihelper import GuiBuilder\n\ndef on_submit(form_data):\n    print(\"Form submitted:\", form_data)\n\n# Method 1: Auto-detect backend (recommended)\ngui = GuiBuilder(config_path=\"my_form.json\")\ngui.set_submit_callback(on_submit)\ngui.show()\n\n# Method 2: Force specific backend\nfrom qtpyguihelper import set_backend\nset_backend('wx')  # or 'qt'\ngui = GuiBuilder(config_path=\"my_form.json\")\ngui.set_submit_callback(on_submit)\n\n# Method 3: Create and run with auto app management\nGuiBuilder.create_and_run(config_path=\"my_form.json\")\n```\n\n## Backend Selection\n\nQtPyGuiHelper supports Qt, wxPython, and tkinter backends with automatic detection and easy switching.\n\n### Automatic Backend Detection\n\nThe library automatically detects available backends in this order:\n1. Check `GUI_BACKEND` environment variable\n2. Check `QT_API` environment variable (for Qt backend)\n3. Use default backend (Qt) if available\n4. Fall back to any available backend\n\n```python\nfrom qtpyguihelper import GuiBuilder, get_backend_info\n\n# Check current backend\ninfo = get_backend_info()\nprint(f\"Using backend: {info['backend']}\")\nprint(f\"Available backends: {info['available_backends']}\")\n\n# Create GUI with auto-detection\ngui = GuiBuilder(config_path=\"form.json\")\nprint(f\"Selected backend: {gui.backend}\")\n```\n\n### Manual Backend Selection\n\n#### Method 1: Environment Variable\n\n```bash\n# Use wxPython backend\nexport GUI_BACKEND=wx\npython your_app.py\n\n# Use Qt backend\nexport GUI_BACKEND=qt\npython your_app.py\n\n# Use tkinter backend\nexport GUI_BACKEND=tk\npython your_app.py\n\n# Use GTK backend\nexport GUI_BACKEND=gtk\npython your_app.py\n\n# For Qt backend, you can also specify the Qt binding\nexport QT_API=pyside6  # or pyqt6\npython your_app.py\n```\n\n#### Method 2: Python Code\n\n```python\nfrom qtpyguihelper import set_backend, GuiBuilder\n\n# Force wxPython backend\nset_backend('wx')\ngui = GuiBuilder(config_path=\"form.json\")\n\n# Force Qt backend\nset_backend('qt')\ngui = GuiBuilder(config_path=\"form.json\")\n\n# Force tkinter backend\nset_backend('tk')\ngui = GuiBuilder(config_path=\"form.json\")\n\n# Force GTK backend\nset_backend('gtk')\ngui = GuiBuilder(config_path=\"form.json\")\n```\n\n#### Method 3: Constructor Parameter\n\n```python\nfrom qtpyguihelper import GuiBuilder\n\n# Force specific backend during construction\ngui = GuiBuilder(config_path=\"form.json\", backend='wx')  # or 'qt', 'tk', 'gtk'\n```\n\n### Backend-Specific Features\n\n#### Qt Backend Features\n- Native Qt styling and themes\n- Advanced widgets and layouts\n- Comprehensive signal/slot system\n- Cross-platform consistency\n- Rich graphics and animation support\n\n#### wxPython Backend Features\n- Native platform look and feel\n- Smaller memory footprint\n- Direct platform API access\n- Extensive widget library\n- Strong macOS integration\n\n#### tkinter Backend Features\n- No additional dependencies (built into Python)\n- Lightweight and fast startup\n- Cross-platform compatibility\n- Simple and reliable\n- Perfect for basic to moderate GUI needs\n\n#### GTK Backend Features\n- Native Linux desktop integration\n- **Automatic GTK version detection** (supports both GTK3 and GTK4)\n- **Automatic OS theme detection** (respects system dark/light mode)\n- Modern GTK 3.0+ / 4.0+ styling and themes\n- Accessibility support\n- Rich widget library\n- Strong integration with GNOME desktop\n- Cross-platform with native look on Linux\n\n**GTK Version Support:**\n- GTK4 (preferred): Automatically detected if available\n- GTK3: Fallback when GTK4 is not available\n- Force specific version with: `export QTPYGUIHELPER_GTK_VERSION=3.0` or `4.0`\n\n**GTK Theme Support:**\n- **Automatic OS theme detection**: Detects and applies system dark/light mode on macOS, Linux, and Windows\n- **macOS**: Reads AppleInterfaceStyle preference\n- **Linux**: Uses gsettings to read GNOME/GTK theme and color-scheme preferences\n- **Windows**: Reads registry for dark mode preference\n- **GTK3 Enhanced Dark Mode**: Uses multiple fallback strategies for reliable dark theme application:\n  - Attempts to use system dark theme variants (Adwaita-dark, current-theme-dark, etc.)\n  - Falls back to custom CSS styling when standard theme switching doesn't work\n  - Provides comprehensive dark styling for all widget types\n- **GTK4 Native Dark Mode**: Uses built-in dark theme support with `gtk-application-prefer-dark-theme`\n- **Manual override**: Set `GTK_THEME` environment variable to override automatic detection\n\n### Backend Compatibility\n\nAll core features work identically across all four backends:\n- ✅ All field types (text, number, date, etc.)\n- ✅ All layout types (form, grid, vertical, horizontal)\n- ✅ Custom buttons with callbacks\n- ✅ Data persistence and loading\n- ✅ Field validation\n- ✅ Nested field names\n- ✅ Tabbed interfaces\n- ✅ Event handling and callbacks\n\n### Testing Backend Availability\n\n```python\nfrom qtpyguihelper import get_available_backends, is_backend_available\n\n# Check what's available\nprint(\"Available backends:\", get_available_backends())\n\n# Check specific backend\nif is_backend_available('tk'):\n    print(\"tkinter is available\")\n\nif is_backend_available('qt'):\n    print(\"Qt backend is available\")\n\nif is_backend_available('gtk'):\n    print(\"GTK backend is available\")\n```\n\n## Supported Field Types\n\n| Type | Description | Supported Properties |\n|------|-------------|---------------------|\n| `text` | Single-line text input | `placeholder`, `default_value` |\n| `email` | Email input field | `placeholder`, `default_value` |\n| `password` | Password input (masked) | `placeholder` |\n| `int` | Integer input (whole numbers) | `min_value`, `max_value`, `default_value` |\n| `float` | Floating-point input with precision control | `min_value`, `max_value`, `default_value`, `format_string` |\n| `number` | Numeric input (legacy - uses float behavior) | `min_value`, `max_value`, `default_value` |\n| `textarea` | Multi-line text input | `placeholder`, `default_value`, `height` |\n| `checkbox` | Checkbox input | `default_value` (boolean) |\n| `radio` | Radio button group | `options` (array), `default_value` |\n| `select` | Dropdown selection | `options` (array), `default_value` |\n| `date` | Date picker | `default_value` (YYYY-MM-DD) |\n| `time` | Time picker | `default_value` (HH:MM) |\n| `datetime` | Date and time picker | `default_value` (ISO format) |\n| `range` | Slider input | `min_value`, `max_value`, `default_value` |\n| `file` | File selection button | `default_value` (\"open\"/\"save\") |\n| `color` | Color picker button | `default_value` (hex color) |\n| `url` | URL input field | `placeholder`, `default_value` |\n\n### Numeric Field Types\n\n- **`int`**: Use for whole numbers (age, quantity, score, etc.). Creates QSpinBox widgets.\n- **`float`**: Use for decimal numbers with precision control. Creates QDoubleSpinBox widgets.\n  - `format_string`: Controls decimal places (e.g., \".2f\" for 2 decimals, \".1f\" for 1 decimal)\n- **`number`**: Legacy type for backward compatibility (behaves like `float`)\n\n#### Float Format Examples\n\n```jsonc\n{\n  \"name\": \"price\",\n  \"type\": \"float\",\n  \"format_string\": \".2f\",  // 2 decimal places (99.99)\n  \"default_value\": 29.99\n}\n\n{\n  \"name\": \"percentage\",\n  \"type\": \"float\",\n  \"format_string\": \".1f\",  // 1 decimal place (95.5)\n  \"max_value\": 100.0\n}\n\n{\n  \"name\": \"precision\",\n  \"type\": \"float\",\n  \"format_string\": \".4f\",  // 4 decimal places (0.1234)\n  \"default_value\": 0.0001\n}\n\n{\n  \"name\": \"scientific\",\n  \"type\": \"float\",\n  \"format_string\": \".2e\",  // Scientific notation (1.23e+06)\n  \"default_value\": 1234567.89\n}\n\n{\n  \"name\": \"general\",\n  \"type\": \"float\",\n  \"format_string\": \".3g\",  // General format (123 or 1.23e+06)\n  \"default_value\": 123.456\n}\n\n{\n  \"name\": \"currency\",\n  \"type\": \"float\",\n  \"format_string\": \",.2f\", // Thousands separator (12,345.67)\n  \"default_value\": 12345.67\n}\n\n{\n  \"name\": \"percent_field\",\n  \"type\": \"float\",\n  \"format_string\": \".1%\",  // Percentage format (85.6%)\n  \"default_value\": 0.856\n}\n```\n\n#### Supported Format String Types\n\n- **`.2f`, `.4f`**: Fixed-point notation with specified decimal places\n- **`.2e`, `.3E`**: Scientific notation (lowercase/uppercase E)\n- **`.3g`, `.2G`**: General format (automatically chooses fixed-point or scientific)\n- **`.1%`, `.2%`**: Percentage format (multiplies by 100 and adds %)\n- **`,.2f`**: Thousands separator with fixed-point notation\n- **`.0f`**: Whole numbers only (no decimal places)\n\n\n## Layout Types\n\n- **`vertical`**: Fields stacked vertically\n- **`horizontal`**: Fields arranged horizontally\n- **`grid`**: Fields in a 2-column grid (label, widget)\n- **`form`**: Qt's form layout (automatic label-widget pairing)\n\n## Configuration Reference\n\n### Window Configuration\n\n```json\n{\n  \"window\": {\n    \"title\": \"Window Title\",\n    \"width\": 800,\n    \"height\": 600,\n    \"resizable\": true,\n    \"icon\": \"path/to/icon.png\"\n  }\n}\n```\n\n### Field Configuration\n\n```jsonc\n{\n  \"name\": \"field_name\",           // Unique identifier (required)\n  \"type\": \"text\",                 // Field type (required)\n  \"label\": \"Field Label\",         // Display label (required)\n  \"required\": false,              // Whether field is required\n  \"default_value\": \"default\",     // Default value\n  \"placeholder\": \"Enter text...\", // Placeholder text\n  \"tooltip\": \"Helpful tip\",       // Tooltip text\n  \"width\": 200,                   // Fixed width in pixels\n  \"height\": 100,                  // Fixed height in pixels\n  \"min_value\": 0,                 // Minimum value (numbers/ranges)\n  \"max_value\": 100,               // Maximum value (numbers/ranges)\n  \"options\": [\"A\", \"B\", \"C\"]      // Options for select/radio fields\n}\n```\n\n### Form Configuration\n\n```jsonc\n{\n  \"layout\": \"form\",               // Layout type\n  \"submit_button\": true,          // Show submit button\n  \"submit_label\": \"Submit\",       // Submit button text\n  \"cancel_button\": true,          // Show cancel button\n  \"cancel_label\": \"Cancel\"        // Cancel button text\n}\n```\n\n### Custom Buttons\n\nQtPyGuiHelper supports adding custom buttons with callbacks to the bottom of the form. Custom buttons appear to the left of the standard submit/cancel buttons.\n\n#### Basic Custom Button Configuration\n\n```jsonc\n{\n  \"custom_buttons\": [\n    {\n      \"name\": \"validate\",          // Unique button identifier\n      \"label\": \"Validate Data\",    // Button text\n      \"tooltip\": \"Validate form before submission\",  // Optional tooltip\n      \"enabled\": true,             // Optional: button enabled state (default: true)\n      \"style\": \"background-color: #007bff; color: white;\",  // Optional: CSS styling\n      \"icon\": \"path/to/icon.png\"   // Optional: button icon\n    },\n    {\n      \"name\": \"export\",\n      \"label\": \"Export JSON\",\n      \"tooltip\": \"Export form data as JSON file\",\n      \"style\": \"background-color: #28a745; color: white; padding: 8px 16px; border-radius: 4px;\"\n    }\n  ]\n}\n```\n\n#### Custom Button Properties\n\n| Property | Type | Required | Description |\n|----------|------|----------|-------------|\n| `name` | string | Yes | Unique identifier for the button (used when registering callbacks) |\n| `label` | string | Yes | Text displayed on the button |\n| `tooltip` | string | No | Tooltip text shown on hover |\n| `enabled` | boolean | No | Whether the button is enabled (default: true) |\n| `style` | string | No | CSS-style string for custom button appearance |\n| `icon` | string | No | Path to icon file for the button |\n\n#### Registering Custom Button Callbacks\n\n```python\nfrom qtpyguihelper import GuiBuilder\n\ndef validate_data_callback(form_data):\n    \"\"\"Custom button callback receives current form data as parameter.\"\"\"\n    print(\"Validating data:\", form_data)\n    # Perform validation logic here\n    if not form_data.get('email'):\n        print(\"Email is required!\")\n    else:\n        print(\"Validation passed!\")\n\ndef export_data_callback(form_data):\n    \"\"\"Export form data to JSON file.\"\"\"\n    import json\n    with open('exported_data.json', 'w') as f:\n        json.dump(form_data, f, indent=2)\n    print(\"Data exported successfully!\")\n\n# Create GUI\ngui = GuiBuilder(\"config.json\")\n\n# Register custom button callbacks\ngui.set_custom_button_callback(\"validate\", validate_data_callback)\ngui.set_custom_button_callback(\"export\", export_data_callback)\n\n# Standard callbacks still work\ngui.set_submit_callback(lambda data: print(\"Form submitted:\", data))\ngui.set_cancel_callback(lambda: print(\"Form cancelled\"))\n\n# Show the GUI\ngui.show()\n```\n\n#### Custom Button Management\n\n```python\n# Get list of all custom button names\nbutton_names = gui.get_custom_button_names()\nprint(\"Available buttons:\", button_names)\n\n# Remove a custom button callback\ngui.remove_custom_button_callback(\"validate\")\n\n# Check which callbacks are registered\nprint(\"Registered callbacks:\", list(gui.custom_button_callbacks.keys()))\n```\n\n#### Complete Example\n\nSee `examples/custom_buttons.json` and `demo_custom_buttons.py` for a complete working example with multiple custom buttons including validation, clear form, preview, and export functionality.\n\n### Nested Field Names\n\nQtPyGuiHelper supports hierarchical data structures using dot notation in field names. This allows you to organize related data into nested JSON objects when saving or loading form data.\n\n#### Basic Usage\n\n```jsonc\n{\n  \"name\": \"global.app_name\",      // Creates: {\"global\": {\"app_name\": value}}\n  \"type\": \"text\",\n  \"label\": \"Application Name\"\n}\n```\n\n#### Example Configuration\n\n```jsonc\n{\n  \"fields\": [\n    {\n      \"name\": \"database.host\",\n      \"type\": \"text\",\n      \"label\": \"Database Host\",\n      \"default_value\": \"localhost\"\n    },\n    {\n      \"name\": \"database.port\",\n      \"type\": \"number\",\n      \"label\": \"Database Port\",\n      \"default_value\": 5432\n    },\n    {\n      \"name\": \"ui.theme\",\n      \"type\": \"select\",\n      \"label\": \"Theme\",\n      \"options\": [\"Light\", \"Dark\", \"Auto\"],\n      \"default_value\": \"Auto\"\n    }\n  ]\n}\n```\n\n#### Output Structure\n\nWhen using nested field names, the saved JSON will have a hierarchical structure:\n\n```json\n{\n  \"database\": {\n    \"host\": \"localhost\",\n    \"port\": 5432\n  },\n  \"ui\": {\n    \"theme\": \"Dark\"\n  }\n}\n```\n\n#### Loading Nested Data\n\nThe library automatically handles loading nested data structures. If you have existing nested JSON data, the GUI will populate fields based on their dot notation names.\n\n## Programming Interface\n\n### Creating a GUI\n\n```python\nfrom qtpyguihelper import GuiBuilder\n\n# From JSON file\ngui = GuiBuilder(config_path=\"form.json\")\n\n# From dictionary\nconfig = {\"window\": {...}, \"fields\": [...]}\ngui = GuiBuilder(config_dict=config)\n```\n\n### Event Handling\n\n```python\n# Form submission\ndef on_submit(form_data):\n    print(\"Submitted:\", form_data)\ngui.set_submit_callback(on_submit)\n\n# Form cancellation\ndef on_cancel():\n    print(\"Cancelled\")\ngui.set_cancel_callback(on_cancel)\n\n# Field changes\ndef on_field_change(field_name, value):\n    print(f\"{field_name} changed to {value}\")\ngui.fieldChanged.connect(on_field_change)\n```\n\n### Runtime Control\n\n```python\n# Get/set form data\nform_data = gui.get_form_data()\ngui.set_form_data({\"username\": \"john\", \"age\": 25})\n\n# Get/set individual fields\nvalue = gui.get_field_value(\"username\")\ngui.set_field_value(\"username\", \"jane\")\n\n# Control field visibility/state\ngui.show_field(\"username\", False)  # Hide field\ngui.enable_field(\"submit_btn\", False)  # Disable field\n\n# Clear all fields\ngui.clear_form()\n```\n\n## Examples\n\nThe library includes comprehensive examples in the `examples/` directory:\n\n### Configuration Files\n- `user_registration.json` - Complete user registration form\n- `settings_form.json` - Application settings with various widget types\n- `project_form.json` - Project data entry form with grid layout\n- `custom_buttons.json` - Demonstrates custom buttons with callbacks\n- `tabbed_config.json` - Complex tabbed interface configuration\n- `float_fields.json` - Float fields with custom formatting\n- `nested_config.json` - Nested field names with dot notation\n\n### Demo Scripts\n\n**Quick Demos** (from root directory):\n```bash\npython demo.py                # Interactive demo launcher\npython demo.py comprehensive  # Full-featured demo\npython demo.py quick-qt       # Simple Qt demo\npython demo.py quick-wx       # Simple wxPython demo\npython demo.py backend        # Backend comparison\n```\n\n**Comprehensive Demo** (from examples directory):\n```bash\n# Interactive demo with all features\npython examples/demo.py\n\n# Specific demos\npython examples/demo.py registration  # User registration form\npython examples/demo.py settings      # Application settings form\npython examples/demo.py project       # Project data entry form\npython examples/demo.py tabs          # Tabbed interface demo\npython examples/demo.py float         # Float fields demo\npython examples/demo.py custom_buttons # Custom buttons demo\npython examples/demo.py wxpython      # wxPython backend demo\npython examples/demo.py tkinter       # tkinter backend demo\npython examples/demo.py gtk           # GTK backend demo\npython examples/demo.py compare       # Backend comparison\npython examples/demo.py unified       # Unified interface (auto-backend)\n```\n\n**Simple Examples**:\n```bash\npython examples/simple_example.py     # Basic getting-started example\npython examples/qt_backend_demo.py    # Qt backend selection demo\n```\n\n### Backend Comparison\n\nThe library provides seamless switching between Qt, wxPython, tkinter, and GTK backends. All backends support all features with identical APIs:\n\n```python\nfrom qtpyguihelper import GuiBuilder, set_backend\n\nconfig = {\n    \"window\": {\"title\": \"Cross-Platform Demo\", \"width\": 500, \"height\": 400},\n    \"layout\": \"form\",\n    \"fields\": [\n        {\"name\": \"name\", \"type\": \"text\", \"label\": \"Name\", \"required\": True},\n        {\"name\": \"age\", \"type\": \"int\", \"label\": \"Age\", \"min_value\": 0, \"max_value\": 120},\n        {\"name\": \"height\", \"type\": \"float\", \"label\": \"Height (m)\", \"format_string\": \".2f\"},\n        {\"name\": \"active\", \"type\": \"checkbox\", \"label\": \"Active\"}\n    ],\n    \"submit_button\": True,\n    \"custom_buttons\": [\n        {\"name\": \"clear\", \"label\": \"Clear Form\", \"tooltip\": \"Clear all fields\"}\n    ]\n}\n\n# Test with Qt backend\nset_backend('qt')\nqt_gui = GuiBuilder(config_dict=config)\n\n# Test with wxPython backend\nset_backend('wx')\nwx_gui = GuiBuilder(config_dict=config)\n\n# Test with tkinter backend\nset_backend('tk')\ntk_gui = GuiBuilder(config_dict=config)\n\n# Test with GTK backend\nset_backend('gtk')\ngtk_gui = GuiBuilder(config_dict=config)\n\n# All GUIs work identically!\n```\n\n**Auto-Backend Selection** (recommended):\n```python\n# Automatically uses the best available backend\ngui = GuiBuilder(config_dict=config)  # No backend selection needed!\n```\n\n## Advanced Usage\n\n### Custom Validation\n\n```python\ndef custom_validator(form_data):\n    if form_data['password'] != form_data['confirm_password']:\n        raise ValueError(\"Passwords don't match\")\n    return True\n\ngui.set_submit_callback(lambda data: custom_validator(data) and save_data(data))\n```\n\n### Dynamic Form Updates\n\n```python\ndef on_country_change(field_name, value):\n    if field_name == 'country' and value == 'USA':\n        gui.show_field('state', True)\n    else:\n        gui.show_field('state', False)\n\ngui.fieldChanged.connect(on_country_change)\n```\n\n### Integration with Data Models\n\n```python\nclass User:\n    def __init__(self, **kwargs):\n        for key, value in kwargs.items():\n            setattr(self, key, value)\n\ndef on_submit(form_data):\n    user = User(**form_data)\n    user.save()  # Save to database\n\ngui.set_submit_callback(on_submit)\n```\n\n## Data Persistence\n\nThe library supports loading and saving form data to JSON files, making it easy to create configuration editors and data entry applications.\n\n### Loading Data\n\n```python\n# Load data from JSON file\ngui.load_data_from_file(\"input_data.json\")\n\n# Load data from dictionary\ndata = {\"field1\": \"value1\", \"field2\": \"value2\"}\ngui.load_data_from_dict(data)\n```\n\n### Saving Data\n\n```python\n# Save current form data to file\ngui.save_data_to_file(\"output.json\")\n\n# Save only non-empty fields\ngui.save_data_to_file(\"output.json\", include_empty=False)\n\n# Save with metadata (includes config info and timestamp)\ngui.save_data_with_metadata_to_file(\"output_with_metadata.json\")\n```\n\n### Example Data Files\n\nInput data files contain the actual field values:\n\n```json\n{\n  \"project_name\": \"Website Redesign\",\n  \"start_date\": \"2025-01-15\",\n  \"priority\": \"High\",\n  \"budget\": 75000,\n  \"active\": true\n}\n```\n\nData files with metadata include additional information:\n\n```json\n{\n  \"project_name\": \"Website Redesign\",\n  \"start_date\": \"2025-01-15\",\n  \"priority\": \"High\",\n  \"_metadata\": {\n    \"config_source\": \"qtpyguihelper\",\n    \"window_title\": \"Data Entry Form\",\n    \"layout\": \"grid\",\n    \"field_count\": 8,\n    \"required_fields\": [\"project_name\"],\n    \"generated_at\": \"2025-07-04T10:30:00\"\n  }\n}\n```\n\n## Requirements\n\n### Python\n- Python 3.7+\n\n### Backend Requirements\n\n#### Qt Backend\n- PySide6 6.5.0+ (recommended) OR PyQt6 6.5.0+\n- qtpy 2.0.0+\n\n#### wxPython Backend\n- wxPython 4.2.0+\n\n#### GTK Backend\n- PyGObject 3.42.0+\n- GTK 3.0+\n\n#### tkinter Backend\n- No additional requirements (built into Python)\n\n### Backend Selection Priority\n1. If all backends are available, Qt is preferred by default\n2. tkinter is second priority (always available with Python)\n3. wxPython is third priority\n4. GTK is fourth priority\n5. Use `GUI_BACKEND` environment variable to force selection\n6. Use `set_backend()` function for programmatic control\n\n## Documentation\n\nQtPyGuiHelper includes comprehensive documentation built with Sphinx:\n\n### 📖 **Online Documentation**\n- **Full Documentation**: [Coming Soon - GitHub Pages]\n- **API Reference**: Complete API documentation with examples\n- **User Guide**: Installation, quick start, and tutorials\n- **Backend Guide**: Detailed comparison and features for each backend\n\n### 🏗️ **Building Documentation Locally**\n\nInstall documentation dependencies:\n```bash\npip install qtpyguihelper[docs]\n```\n\nBuild and view documentation:\n```bash\n# Quick build and open\n./docs.sh build \u0026\u0026 ./docs.sh open\n\n# Or step by step\ncd docs\nmake html\nopen _build/html/index.html  # macOS\n# or navigate to file://path/to/docs/_build/html/index.html\n```\n\n**Development with Live Reload**:\n```bash\n./docs.sh serve\n# Opens http://127.0.0.1:8000 with auto-reload on changes\n```\n\n### 📚 **Documentation Content**\n- **Installation Guide**: Multiple backend setup options\n- **Quick Start**: Get up and running in minutes\n- **Comprehensive Examples**: Real-world usage patterns\n- **API Reference**: Auto-generated from docstrings\n- **Backend Comparison**: Choose the right backend for your needs\n- **Advanced Topics**: Custom widgets, validation, theming\n\n### 🛠️ **Documentation Tools**\n- **docs.sh**: Convenient build script with multiple commands\n- **GitHub Actions**: Automated documentation deployment\n- **Sphinx**: Professional documentation generation\n- **Read the Docs Theme**: Clean, responsive design\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjacobwilliams%2Fqtpyguihelper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjacobwilliams%2Fqtpyguihelper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjacobwilliams%2Fqtpyguihelper/lists"}