Edifice: a declarative GUI library for Python

Overview

Edifice: a declarative GUI library for Python

tests codecov

Installation for version 0.0.5:

    pip install pyedifice

Detailed Documentation: Read the docs

Edifice is a Python library for building reactive UI, inspired by modern Javascript libraries such as React. Edifice makes it simple to build a fully reactive UI without ever leaving Python, getting the best of both worlds:

  • Modern paradigms from web development that simplify UI creation
  • Fast iteration via hot reloading
  • Seamless integration with the Python ecosystem (standard library, numpy, matplotlib, pandas, etc)
  • A native desktop app without the overhead of bundling a browser.

Edifice uses Qt as a backend (although it could be generalized to other backends).

Getting Started

Edifice is inspired by React, so if you have React experience, you'll find Edifice to be very similar. For example, for the React setState function, Edifice has set_state, and for React's this.props, Edifice has self.props. All function names use underscores instead of camel case to conform to Python standards, and "Component" is removed from functions like shouldComponentUpdate (renamed to should_update).

See the tutorial to get started.

Why Edifice?

The premise of Edifice is that GUI designers should only need to worry about what is rendered on the screen, not how the content is rendered. Most existing GUI libraries in Python, such as Tkinter and Qt, operate imperatively. To create a dynamic application using these libraries, you must not only think about what to display to the user given state changes, but also how to issue the commands to achieve the desired effect.

Edifice allows you to describe the GUI as a function mapping state to displayed widgets, leaving the how to the library. User interactions update the state, and state changes update the GUI. Edifice makes it possible to write code like:

View(layout="row")(
    Button("Add 5", on_click=lambda:self.set_state(data=self.data + 5)),
    *[Label(i) for i in self.data]
)

and get the expected result: the values in self.data will be displayed, and clicking the button will add 5 to the array, and this state change will automatically be reflected in the GUI. You only need to specify what is to be displayed given the current state, and Edifice will work to ensure that the displayed widgets always correspond to the internal state.

Edifice is designed to make GUI applications easier for humans to reason about. Thus, the displayed GUI always reflect the internal state, even if an exception occurs part way through rendering --- in that case, the state changes are unwound, the display is unchanged, and the exception is re-raised for the application to handle. You can specify a batch of state changes in a transaction, so that either all changes happen or none of them happens. There is no in-between state for you to worry about.

Declarative UIs are also easier for developer tools to work with. Edifice provides two key features to make development easier:

  • Dynamic reloading of changed source code. This is especially useful for tweaking the looks of your application, allowing you to test if the margin should be 10px or 15px instantly without closing the app, reopening it, and waiting for everything to load.
  • Component inspector. Similar to the Inspect Elements tool of a browser, the component inspector will show you all Components in your application along with the props and state, allowing you to examine the internal state of your complex component without writing a million print statements. Since the UI is specified as a (pure) function of state, the state you see completely describes your application, and you can even do things like rewinding to a previous state.

QML is another declarative GUI framework for Qt. Edifice differs from QML in these aspects:

  • Edifice interfaces are created purely in Python, whereas QML is written using a separate language.
  • Because Edifice interfaces are built in Python code, binding the code to the declared UI is much more straightforward.
  • Edifice makes it easy to create dynamic applications. It's easy to create, shuffle, and destroy widgets because the interface is written in Python code. QML assumes a much more static interface.

An analogy is, QML is like HTML + JavaScript, whereas Edifice is like React.js. While QML and HTML are both declarative UI frameworks, they require imperative logic to add dynamism. Edifice and React allow fully dynamic applications to be specified declaratively.

How it works:

An Edifice component encapsulates application state and defines the mapping from the state to UI in the render function. The state of a Component is divided into props and state. Props are state passed to the Component in the constructor, whereas state is the Component's own internal state. Changes to props and state will trigger a rerender of the Component and all its children. The old and new component trees will be compared to one another, and a diffing algorithm will determine which components previously existed and which ones are new (the algorithm behaves similarly to the React diff algorithm). Components that previously existed will maintain their state, whereas their props will be updated. Finally, Edifice will try to ensure that the minimal update commands are issued to the UI. All this logic is handled by the library, and the Components need not care about it.

Currently, Edifice uses Qt under the hood, though it could be adapated to delegate to other imperative GUI frameworks as well.

Development Tools

Edifices also offers a few tools to aid in development.

set_trace

PDB does not work well with PyQt5 applications. edifice.set_trace is equivalent to pdb.set_trace(), but it can properly pause the PyQt5 event loop to enable use of the debugger (users of PySide2 need not worry about this).

Dynamic reload

One other advantage of declarative code is that it is easier for humans and machines to reason about. Edifice takes advantage of this by offering hot reloading of Components. When a file in your application is changed, the loader will reload all components in that file with preserved props (since that state comes from the caller) and reset state. Because rendering is abstracted away, it is simple to diff the UI trees and have the Edifice renderer figure out what to do using its normal logic.

To run your application with dynamic reload, run:

python -m edifice path/to/app.py RootComponent.

This will run app.py with RootComponent mounted as the root. A separate thread will listen to changes in all Python files in the directory containing app.py (recursing into subdirectories), and will reload and trigger a re-render in the main thread. You can customize which directory to listen to using the --dir flag.

Component Inspector

The Edifice component inspector shows the Component tree of your application along with the props and state of each component.

Other information

Contribution

Contributions are welcome; feel free to send pull requests!

License

Edfice is MIT Licensed.

Edifice uses Qt under the hood, and both PyQt5 and PySide2 (and PySide6) are supported. Note that PyQt5 is distributed with the GPL license while PySide2 and PySide6 are distributed under the more flexible LGPL license.

Owner
David Ding
Research Engineer. Harvard CS 2016
David Ding
A small GUI random roll call program made by Python.

A small GUI random roll call program made by Python.

Yuchen Ren 0 Feb 21, 2022
A little Python library for making simple Electron-like HTML/JS GUI apps

Eel Eel is a little Python library for making simple Electron-like offline HTML/JS GUI apps, with full access to Python capabilities and libraries. Ee

Chris Knott 5.4k Jan 07, 2023
Learn to build a Python Desktop GUI app using pywebview, Python, JavaScript, HTML, & CSS.

Python Desktop App Learn how to make a desktop GUI application using Python, JavaScript, HTML, & CSS all thanks to pywebview. pywebview is essentially

Coding For Entrepreneurs 55 Jan 05, 2023
GUI based app made in python using tkinter

Virtual Keyboard A GUI application made in python using tkinter This is my first ever proper GUI based application project after learning tkinter rece

AbhineetK 10 Dec 10, 2022
A desktop application for JupyterLab, based on Electron.

A desktop application for JupyterLab, based on Electron.

JupyterLab 2.1k Jan 02, 2023
This is the new and improved Plex Automatic Pre-roll script with a GUI

Rollarr This is the new and improved Automatic Pre-roll script with a GUI for Plex now called Rollarr! It should be stable but if you find a bug pleas

164 Nov 04, 2022
These are some useful tkinter utilities that i like to personally use.

ntkutils nefs tkinter utilities These are some useful tkinter utilities that i like to personally use. I upload this here because someone might wants

nef 7 Dec 06, 2022
Tkinker GUI for a college project.

GuiUtilities Pequeña suite de utileria con Tkinter enfocada en sistemas Linux. Lista de trabajo Crear archivo Copiar archivo a otro dir Editar con un

1hiking 2 Nov 25, 2021
Missing widgets and components for Qt-python

superqt! "missing" widgets and components for PyQt/PySide This repository aims to provide high-quality community-contributed Qt widgets and components

napari 0 Nov 11, 2022
Write interactive web app in script way.

PyWebIO Write interactive web app in script way. [Document] | [Demos] | [Why PyWebIO?] English | 中文 PyWebIO provides a series of imperative functions

PyWebIO 3.6k Dec 31, 2022
Pyint is the graphic software which is written in Python

Pyint About Pyint Pyint is the graphic software which is written in Python(I use the Turtle graphics). The name 'Pyint' is compound word of 'Python' a

John 1 Nov 06, 2021
Make nixos usable for non-technical users through a settings / package management GUI.

Nix-Gui Make nixos usable for non-technical users through a settings / package management GUI. Motives The declarative nature of ni

547 Dec 31, 2022
Quebra cabeça - Utilizando biblioteca do python: PyQt5

Puzzle 3x3 PyQt5 - Windows Quebra cabeça - Utilizando biblioteca do python: PyQt5 Para testar este quebra cabeça na sua maquina, primeiramente faça o

Matheus Marsal 1 Dec 21, 2021
A Windows Dock Widget Written In Pure Python

VEПUS A Windows Dock Widget Written In Pure Python What is Venus? Venus is a Dock Widget for your desktops interface. It adds a couple of really cool

Secrets 18 Dec 30, 2022
Chatterpatter - A simple GUI complex backend Chat Application made using python

Chatterpatter - A simple GUI complex backend Chat Application made using python

Gurneet Singh 2 Jan 08, 2022
A GUI frontend for the Kamyroll-API using Python and PySide6

Kamyroll-GUI A GUI frontend for the Kamyroll-API using Python and PySide6 Usage When starting the application you will be presented with a list and so

Simon Sawicki 15 Oct 09, 2022
Advanced GUI Calculator with Beautiful UI and Clear Code.

Advanced GUI Calculator with Beautiful UI and Clear Code.

Mohammad Dori 3 Jul 15, 2022
HDLG is a modern cross-platform GUI for hdl-dump with Batch installation capabilities.

HDLG is a modern cross-platform GUI for hdl-dump with Batch installation capabilities. Looking for Artwork This project is looking for an Icon an

8 Dec 03, 2022
yfinance is a library where you can see stocks, crypto and tickers information

yfinance is a library where you can see stocks, crypto and tickers information.

Joaquin 3 Nov 19, 2022
Key Cast - Cast your key presses and mouse clicks on the screen, while casting your favorite application on the screen. Better than the rest.

Key Cast Screen cast your keyboard and mouse clicks in style Project Homepage » View Demo · Report Bug · Request Feature Table of Contents Introductio

Mehul Singh Teya 13 Dec 23, 2022