A modern GTK3 desktop application for managing entity-based data with XML storage. This application provides a user-friendly interface for performing CRUD (Create, Read, Update, Delete) operations on entities defined in an XML configuration file, following the Lua ArtNazarov/luassg site generator XML format.
The application now includes a Configuration menu that allows you to directly edit XML configuration files using an integrated XML tree editor:
- Configuration Menu: Main menu with "Configuration" dropdown
- Direct XML Editing: Two menu items for editing common configuration files:
- Open ./data/CONST.xml: Edit the CONST.xml configuration file
- Open ./data/pagination.xml: Edit the pagination.xml configuration file
- Integrated Editor: Launches
dialog_xml_tree_editor.pyas a standalone process - Automatic File Creation: Missing XML files are automatically created if they don't exist
- Click Configuration in the main menu bar
- Select either "Open ./data/CONST.xml" or "Open ./data/pagination.xml"
- The application automatically:
- Checks if the XML file exists (creates it if missing)
- Verifies the XML tree editor script is available
- Launches the editor in a new process with the selected file
- Edit the XML file in a dedicated tree-based editor interface
- Changes are saved back to the original file
- Process Isolation: XML editor runs as a separate process, keeping the main app responsive
- File Validation: Ensures XML files follow proper structure before editing
- Path Resolution: Automatically finds the editor script in the same directory as app.py
- Error Handling: Comprehensive error messages if files or editor are missing
- 🔧 Direct Configuration Editing: Edit XML configs without leaving the application
- 🌳 Visual XML Editing: Use a tree-based editor for complex XML structures
- 🔄 Live Updates: Changes made in the editor are immediately saved
- ⚡ Non-blocking: Main application remains responsive while editing
- Multi-Entity Management: Automatically creates tabs for each entity defined in XML
- CRUD Operations: Full Create, Read, Update, Delete functionality for records
- Dynamic Entity Definition: Define custom entities with configurable fields
- Field Type Support: Two field types supported:
oneline(single-line text) andmultiline(multi-line text area) - Entity Management: Create, edit, and delete entities with automatic file system updates
- luassg XML Format: Compatible with ArtNazarov/luassg XML structure
- Persistent XML Storage: All data stored in structured XML files
- Clean Architecture: Clear separation between data loading and UI rendering
- Comprehensive Testing: 11 tests with full coverage using pytest
- Configuration Menu: Integrated XML tree editor for editing configuration files
./
├── app.py # Main application
├── tests.py # Pytest test suite (11 tests)
├── dialog_xml_tree_editor.py # XML tree editor for configuration files
├── entities_description.xml # Entity definitions
├── README.md # This file
└── data/ # Data storage directory
├── CONST.xml # Configuration file (editable via menu)
├── pagination.xml # Configuration file (editable via menu)
├── posts/ # Example entity directory
│ ├── posts-[uuid].xml # Entity files follow: entity-entityId.xml format
│ └── ...
├── news/
├── quotes/
└── gallery/
└── gallery-37158403-3cfe-4922-92e2-46326f0eb571.xml # Example file
# For Arch Linux
git clone https://github.com/ArtNazarov/entity_xml_crud_app.git
cd entity_xml_crud_app
sudo pacman -S python python-gobject gtk3 python-pytest python-lxml
python app.pypython -m pytest tests.py -vsudo pacman -S python python-gobject gtk3 python-pytest python-lxmlsudo apt-get install python3 python3-gi python3-gi-cairo gir1.2-gtk-3.0 python3-pytest python3-lxmlsudo dnf install python3 python3-gobject gtk3 python3-pytest python3-lxmlpip install PyGObject pytest lxmlThe application follows a clean architecture with clear separation of concerns:
load_xml_data(): Loads all data from XML files into memorysave_entities_to_xml(): Saves entity definitions to XML- In-memory data structure with entities, fields, and records
render_xml_data_state(): Clears UI and renders tabs based on in-memory datacreate_entity_tab(): Creates individual entity tabscreate_management_tab(): Creates the management tab (always last)create_menu_bar(): Creates the main menu with configuration options
on_open_const_xml(): Handles opening CONST.xml in the XML tree editoron_open_pagination_xml(): Handles opening pagination.xml in the XML tree editoropen_xml_in_editor(): Common method for launching the XML tree editor
- No UI flickering: Tabs don't disappear during refresh
- Robust updates: Entity structure changes handled gracefully
- Clean separation: Data operations separate from UI rendering
- Integrated configuration: Edit XML files directly from the application
The application automatically creates necessary directories and files:
- Creates
./data/directory if it doesn't exist - Creates
./entities_description.xmlwith default structure if missing - Loads existing entities and data on startup
- Click Configuration in the main menu bar
- Select "Open ./data/CONST.xml" to edit the CONST.xml file
- Select "Open ./data/pagination.xml" to edit the pagination.xml file
- The XML tree editor opens in a new window for visual XML editing
- Make changes and save - they are immediately reflected in the file
Entities are defined in entities_description.xml following the luassg format:
<?xml version='1.0' encoding='utf-8'?>
<entities>
<entity>
<entity_name>gallery</entity_name>
<entity_fields>
<entity_field>
<field_name>title</field_name>
<field_type>oneline</field_type>
</entity_field>
<entity_field>
<field_name>description</field_name>
<field_type>multiline</field_type>
</entity_field>
<entity_field>
<field_name>alt</field_name>
<field_type>oneline</field_type>
</entity_field>
<entity_field>
<field_name>src</field_name>
<field_type>oneline</field_type>
</entity_field>
<entity_field>
<field_name>comment</field_name>
<field_type>multiline</field_type>
</entity_field>
</entity_fields>
</entity>
<!-- More entities... -->
</entities>oneline: Single-line text input field (Gtk.Entry)multiline: Multi-line text area with scrollbars (Gtk.TextView in Gtk.ScrolledWindow)
- New Record: Create new record with dialog
- Edit Record: Modify selected record
- Delete Record: Remove selected record with confirmation
- Refresh: Reload data for this entity only
- New Entity: Define new entity with custom fields
- Edit Entity: Modify entity structure (automatically renames files)
- Delete Entity: Remove entity and all associated data with confirmation
- Refresh All: Reload all data and refresh entire UI
- Open CONST.xml: Edit the CONST.xml configuration file
- Open pagination.xml: Edit the pagination.xml configuration file
./data/{entity_name}/{entity_name}-{unique_id}.xml
Example: ./data/gallery/gallery-37158403-3cfe-4922-92e2-46326f0eb571.xml
./data/CONST.xml: Application configuration constants./data/pagination.xml: Pagination settings and configuration
The application saves records in the ArtNazarov/luassg XML format:
<?xml version='1.0' encoding='utf-8'?>
<gallery id="37158403-3cfe-4922-92e2-46326f0eb571">
<title>The kitten</title>
<description>Some description</description>
<alt>Some alt text</alt>
<src>https://upload.wikimedia.org/wikipedia/commons/9/9b/Photo_of_a_kitten.jpg</src>
<comment>my comment</comment>
</gallery>Key characteristics:
- Root element name matches entity name
idattribute on root element contains the record identifier- Field elements as direct children of root
- XML declaration with encoding
- Proper indentation for readability
entities_description.xml:
<?xml version='1.0' encoding='utf-8'?>
<entities>
<entity>
<entity_name>posts</entity_name>
<entity_fields>
<entity_field>
<field_name>title</field_name>
<field_type>oneline</field_type>
</entity_field>
<entity_field>
<field_name>message</field_name>
<field_type>multiline</field_type>
</entity_field>
</entity_fields>
</entity>
<entity>
<entity_name>news</entity_name>
<entity_fields>
<entity_field>
<field_name>caption</field_name>
<field_type>multiline</field_type>
</entity_field>
<entity_field>
<field_name>longread</field_name>
<field_type>multiline</field_type>
</entity_field>
</entity_fields>
</entity>
<entity>
<entity_name>quotes</entity_name>
<entity_fields>
<entity_field>
<field_name>phrase</field_name>
<field_type>oneline</field_type>
</entity_field>
<entity_field>
<field_name>author</field_name>
<field_type>oneline</field_type>
</entity_field>
</entity_fields>
</entity>
<entity>
<entity_name>gallery</entity_name>
<entity_fields>
<entity_field>
<field_name>title</field_name>
<field_type>oneline</field_type>
</entity_field>
<entity_field>
<field_name>description</field_name>
<field_type>multiline</field_type>
</entity_field>
<entity_field>
<field_name>alt</field_name>
<field_type>oneline</field_type>
</entity_field>
<entity_field>
<field_name>src</field_name>
<field_type>oneline</field_type>
</entity_field>
<entity_field>
<field_name>comment</field_name>
<field_type>multiline</field_type>
</entity_field>
</entity_fields>
</entity>
</entities>data/gallery/gallery-37158403-3cfe-4922-92e2-46326f0eb571.xml:
<?xml version='1.0' encoding='utf-8'?>
<gallery id="37158403-3cfe-4922-92e2-46326f0eb571">
<title>The kitten</title>
<description>Some description</description>
<alt>Some alt text</alt>
<src>https://upload.wikimedia.org/wikipedia/commons/9/9b/Photo_of_a_kitten.jpg</src>
<comment>my comment</comment>
</gallery>The project includes 11 comprehensive pytest tests that verify:
# Run all tests
python -m pytest tests.py -v
# Run specific test category
python -m pytest tests.py::test_load_entities -v
# Test coverage includes:
# ✓ Entity loading and parsing
# ✓ Field type validation
# ✓ File naming conventions (entity-entityId.xml)
# ✓ Directory structure
# ✓ CRUD operations with luassg format
# ✓ Integration tests
# ✓ Loading existing luassg format filesThe application is specifically designed to work with the ArtNazarov/luassg XML format:
- Records are saved with root element name = entity name
idattribute on root element contains record identifier- Field values are stored as child elements
- Automatic handling of filename pattern:
{entity_name}-{entity_id}.xml
The new configuration menu feature integrates seamlessly:
- Menu Bar Integration: Added to main window without disrupting existing layout
- Process Management: Uses
subprocess.Popento launch editor independently - File Validation: Checks if XML files exist and creates them if missing
- Error Handling: Provides user feedback if editor script is not found
- Path Resolution: Automatically locates
dialog_xml_tree_editor.pyin the same directory
- Empty window on startup - Proper initialization sequence
- Tabs disappearing on refresh - Separate data loading from UI rendering
- Entity Management tab position - Always appears as last tab
- Window blanking on entity updates - Added safety checks and proper UI refresh
- In-memory data caching for quick access
- Selective UI updates (entity vs full refresh)
- Efficient XML parsing with error handling
- Proper handling of luassg format files
- Independent process for XML editing (non-blocking)
- Confirmation dialogs for destructive actions
- Real-time data synchronization
- Clear error messages
- Responsive UI with proper scrolling
- Automatic file renaming when entity names change
- Integrated configuration editing via menu
- Visual XML tree editing for complex structures
Issue: "ModuleNotFoundError: No module named 'gi'" Solution: Install python-gobject package
sudo pacman -S python-gobject # Arch
sudo apt-get install python3-gi # Ubuntu/DebianIssue: Window appears empty on startup
Solution: Ensure entities_description.xml exists and is valid XML
Issue: Tabs disappear after refresh Solution: This bug has been fixed in current version. Update to latest code.
Issue: XML files not loading correctly
Solution: Ensure files follow luassg format with id attribute on root element
Issue: "XML tree editor not found" error
Solution: Ensure dialog_xml_tree_editor.py is in the same directory as app.py
Issue: Configuration menu items don't work
Solution: Install python-lxml: pip install lxml or sudo pacman -S python-lxml
Add debug prints to load_entities() method to see XML parsing issues.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Write tests for new features
- Maintain backward compatibility with luassg format
- Follow Python PEP 8 style guide
- Update documentation as needed
- Ensure all 11 tests pass before submitting PR
This project is licensed under the MIT License - see the LICENSE file for details.
- GTK3 team for the excellent GUI toolkit
- Python community for amazing libraries
- Pytest team for robust testing framework
- All contributors who helped fix bugs and improve the application
- ArtNazarov/luassg for the XML format specification
Artem Nazarov - GitHub
Project Link: https://github.com/ArtNazarov/entity_xml_crud_app
EntityCRUDApp: Main application classRecordDialog: Dialog for creating/editing recordsEntityDialog: Dialog for managing entity definitions
load_xml_data(): Master data loaderrender_xml_data_state(): Master UI rendereron_refresh_all(): Refresh everything (management tab)on_refresh_entity(): Refresh single entityopen_xml_in_editor(): Launch XML tree editor
User Action → Load XML Data → Update Memory → Render UI State → Show Window
Configuration Menu → Launch Editor → Edit XML → Save Changes
- Launch application:
python app.py - Edit configuration: Click Configuration → Open ./data/CONST.xml
- XML tree editor opens in a new window
- Edit the XML structure visually
- Save changes
- Add new entity: Go to "Entity Management" tab → "New Entity"
- Name: "tasks"
- Fields: "name" (oneline), "description" (multiline)
- Add records: Go to "tasks" tab → "New Record"
- Fill in fields and save (creates
tasks-{uuid}.xmlin luassg format)
- Fill in fields and save (creates
- Edit structure: Go to "Entity Management" → Select "tasks" → "Edit Entity"
- Add field: "priority" (oneline)
- UI automatically updates with new column
- Refresh data: Click "Refresh All" to reload from disk
- Edit pagination: Click Configuration → Open ./data/pagination.xml
- Configure pagination settings for your data
That's it! Your data is automatically saved in the luassg XML format and configuration files can be edited directly from the application menu.
The application features a fully responsive GTK3 interface that adapts to different window sizes and screen resolutions.
- Column Resizing: TreeView columns automatically adjust width based on available space
- Minimum Window Size: Set to 800×600 pixels to ensure usability
- Form Adaptation: Input fields and labels rearrange from horizontal to vertical layout on narrow screens
- Entity List: Columns hide or resize based on available width
- Dialog Forms: Field layouts adapt to dialog size with intelligent spacing
- Tab Interface: Tab labels truncate with ellipsis when space is limited
# Core responsive settings
window.set_size_request(800, 600) # Minimum usable size
scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
column.set_resizable(True)
column.set_expand(True) # Key columns expand first






