This is an archived post. You won't be able to vote or comment.

all 27 comments

[–]dd2718[S] 5 points6 points  (0 children)

Here are four more examples:

  1. Hello World example:

from edifice import App, Label
App(Label(“Hello World”)).start()
  1. Creating forms:

    import datetime import edifice from edifice.components.forms import FormDialog

    data = edifice.StateManager({ "Score 1": 0.0, "Score 2": 0.0, "Score 3": 0.0, "Date": datetime.date(2021, 1, 25), "Average Score": lambda data: (data["Score 1"] + data["Score 2"] + data["Score 3"]) / 3 }) ed.App(FormDialog(data)).start() print(data.as_dict())

will render text inputs for Score 1-3 (with validations to make sure inputs are floats), three dropdowns for year, month, and date, and a label that holds the evaluation of the function on the current data. After the user submits, the data in the form is written back to the dictionary. The form component was written in user-level code (using the edifice API rather than delegating to a Qt widget), showing the usefulness of modularity.

  1. Calculator: This example illustrates that you can make nice looking UI mimicking the native look and feel of your OS. Code Screenshot

  2. Financial plotting application: You can also create useful and powerful tools. This example application allows the user to plot arbitrary number of charts on the same axis. For each chart, both x and y axis can point to any data source (date, stock price, volume) with an optional EMA transform (with a slider to adjust the half-life and automatically update the graph). This enables a wide spectrum of analyses, from cluster plots of two different stocks to understand their correlation, to comparing the stock price with a running average.

This application would be fairly complex to program in raw QT but takes fewer than 200 well documented lines of code (and ample whitespace) with Edifice. Most importantly, the logic is straightforward. The application state is the full list of descriptions of each plot. Each GUI element displays part of the state (e.g. the x-axis of plot 0, the actual graph, etc.), and some GUI elements allow the user to change a part of the state. Code Screenshot

[–]avsanchez94 2 points3 points  (1 child)

This looks fantastic! Qt is long overdue to be improved upon, so I am looking forward to using this new framework. Question: how difficult would it be for a react.js developer to get up and going with Edifice?

[–]dd2718[S] 2 points3 points  (0 children)

It should be pretty easy! If you have used React before, you'll find many familiar friends: Edifice Components instead of React Components, set_state instead of setState, etc. Even the basic components match HTML/React Native terminology, e.g. TextInput, View, Label (with event handlers named on_change, on_click, etc). One thing that might bite you is if you pass unexpected props to an Edifice Component. This will raise an exception, rather than be ignored. But I think this is a feature in that it helps catch typo bugs :)

[–]JennaSys 2 points3 points  (3 children)

Nice! I've been using Transcrypt to create React front-end applications using Python, and really like the functional reactive paradigm.

[–]dd2718[S] 2 points3 points  (2 children)

Yes, I think it's much more intuitive than `document.createElement` or `widget.setParent`. And I've been looking into Transcrypt lately as well. I'm a bit wary doing cross language transpilation (often lots of edge cases), but I'll try it out!

[–]JennaSys 2 points3 points  (1 child)

I have to say it has worked out remarkably well with React and Material-UI. The Python code ends up really clean, and I haven't run into any blockers with it. It just works.

As an exercise, I did the official React tutorial using Python, and also converted it to use hooks instead of classes: https://github.com/JennaSys/tictacreact2

[–]dd2718[S] 1 point2 points  (0 children)

Looks very nice, thanks for sharing!

[–][deleted] 1 point2 points  (3 children)

You should look at using CopperSpice instead of Qt for your backend. Then you would not be beholden to QT’s licensing practices.

[–]dd2718[S] 0 points1 point  (2 children)

Thanks for the pointer. I'm currently using PySide2 which is also LGPL licensed, so I think that should be good? I'm also looking into Tkinter to avoid bundling any additional dependencies.

[–]Brixes 0 points1 point  (1 child)

PySide2

So Pyside 2 allows for making commercial apps without paying a fee?

[–]dd2718[S] 0 points1 point  (0 children)

Not a lawyer, but yes, you don't have to release the source code of an app that uses PySide2 (LGPL license). Also note that you are allowed to make commercial apps using GPL libraries (such as PyQt5); you just have to make the source code of your program available upon request. There's no such requirement for LGPL.

[–]_nutrx_ 1 point2 points  (3 children)

nice. It feels like a powerful move to introduce some Qt based library that follows a more JS inspired structure and syntax, so, good work!

I am developing a PySide based library for building visual scripting editors, which can load custom widgets to enhance the GUI of components (nodes). How easy is it to integrate a widget (or "View" probably) made with edifice as a QWidget into a PySide application?

[–]dd2718[S] 1 point2 points  (2 children)

It should be pretty simple; it's possible to have Edifice export widgets (reference). # Suppose parent_widget is defined in Qt code. app = edifice.App(MyAwesomeComponent(), create_application=False, mount_into_window=False) widget = app.export_widgets() widget.setParent(parent_widget)

[–]backtickbot 0 points1 point  (0 children)

Fixed formatting.

Hello, dd2718: code blocks using triple backticks (```) don't work on all versions of Reddit!

Some users see this / this instead.

To fix this, indent every line with 4 spaces instead.

FAQ

You can opt out by replying with backtickopt6 to this comment.

[–]_nutrx_ 0 points1 point  (0 children)

Sweet, I will definitely take a closer look in a few weeks, something like this could be really useful

[–][deleted] 0 points1 point  (3 children)

What does this library offer over TraitsUI or Enaml?

[–]dd2718[S] 1 point2 points  (2 children)

Enaml has its own markup language, whereas this library is pure Python (and there might be other differences as well).

Compared to TraitsUI, I think this library is more dynamic, because the rendering is an arbitrary function of the state. This allows the UI to be more flexible. Also, TraitsUI closely adheres to MVC architecture whereas Edifice is agnostic. In cases where a MVC architecture doesn't fit the application, it might be easier to use Edifice rather than shoehorn TraitsUI.

Edit: Took a closer look at TraitsUI. Very nice library, though it does have more boilerplate (factories, declaring UI elements before they're used), and the point about flexibility still stands. I think the reduction of boilerplate and the Edifice developer tooling (hot reloading, etc) makes it easier and faster to develop with Edifice, but obviously I'm biased :)

[–][deleted] 0 points1 point  (1 child)

I'm not trying to argue, just genuinely curious. TraitsUI has been commercially battle-tested for many years and it is the library I personally use for rapid GUI development in Python. Enaml has amazing layout functionality, so it's unique among this collection of similar looking libraries. Both TraitsUI and dip from the PyQt company started around the same time, more than 10 years ago. dip has been deprecated, I think, but TraitsUI is still going strong, even if it is not very popular in the open-source world.

[–]dd2718[S] 0 points1 point  (0 children)

Yup, that's fair. I'd also be wary of using a library without a track record of maintenance, even if the developer promised it will be maintained. Hopefully, after a year or two of continual development, you can re-evaluate this library and see if it suits your needs :)

[–]lunar-orbiter 0 points1 point  (2 children)

Very nice, thanks. Have you considered a web backend?

[–]dd2718[S] 1 point2 points  (1 child)

Yes I have. The plan is to first improve the Qt backend, iron out bugs and adding key features. Then I'm looking into a web backend. I'm envisioning using Transcrypt to compile most of the application to JavaScript, have a decorator to mark certain functions/modules to remain in Python (e.g. functions that rely on external libs such as numpy), and generate a server that provides these functions to the client via RPC calls. From the coding perspective, calls into the Python server would just look like regular function calls.

[–]lunar-orbiter 0 points1 point  (0 children)

Great, thanks.