Hacker News new | past | comments | ask | show | jobs | submit login
Python GUIs (pythonguis.com)
130 points by gilad on June 14, 2023 | hide | past | favorite | 95 comments



I sometimes miss the good old days of visual basic and delphi when I could create a gui that just worked in seconds, help pages via F1 and quick access to all events possible through simple gui clicks.

A few days ago I tried getting a simple PyQtWebengine example working using pyqt6 and failed miserably. It was a frustrating experience for sure


Tcl/Tk was fairly amazing for getting a simple UI going.

Back in the dialup days, my modem was plugged into a homebrew Linux firewall/router so that I could use the Internet from multiple machines at once. Which outside of a large business or college campus, was considered pretty much advanced wizardry back then. The problem was that I had one phone line and couldn't tie it up all the time. I wanted to be able to open a program on the desktop of another computer, click a button marked "connect to internet" and have that talk to the server to start the dialup process. And then also a "disconnect" button to hang up later. With a little text box to show any errors and whatnot. There were some half-solutions to this in existence at the time, but nothing that fit my exact use case.

I had been beating my head against various Perl experiments which weren't getting me anywhere until finally someone on IRC said, "oh, have you tried Tcl/Tk?"

Tcl was so easy to learn that I had a working proof of concept by the end of the day. Another couple of days to tidy it up. Used it daily for a few years until DSL came to my area.


I agree with this. I whipped up a small tcl/tk project, used it for years, worked everywhere. Every time I tried some other framework in Python, I always ended up stepping on rakes. Nothing ever felt right.

These days, if tcl/tk doesn't suffice for my project, then I just move onto another environment entirely.


Ttk exists :)


i had great experiences with ruby/tk as well; it was just the pain of deployment that made me give up on it.


This is a constant ask every time a thread about desktop UI design comes up. Everyone wants a new Visual Basic, nobody wants to use the alternatives. The VB language itself likely doesn't appeal to people nowadays but the building blocks the UI provided is still unparalleled and everyone has fond memories of how easy prototyping applications is with it.


1990s PC economics produced Visual Basic. Microsoft was able to write off the development cost of the Visual Studio suite as an investment in the further entrenchment of Windows -- something no third party devtools company could directly profit from. So VB was designed to be the lowest of the low friction paths to developing software that locked users and businesses into win32. The single platform focus (supporting other platforms would have defeated the purpose) also helped keep the IDE lean and speedy.

Former VB devs pine for the usability and speed they once enjoyed. But most tech ecosystems that are self-contained enough to benefit from focused/lightweight devtools can't support a player large enough to develop them. And the ecosystems that are big enough are managed by megacorps that are more interested in brokering consumer data than streamlining the developer experience. I too would love to see a renaissance of RAD but I can't figure out who would pay for it.


I have recently tried JavaFX again, and while it definitely involves some getting used to, it has SceneBuilder as a drag’n’drop GUI editor, and that is hard to beat. Plus it will run on every platform and you can choose from plenty languages.

It is a niche (let’s be honest, desktop development is also one), but it has a surprising amount of libraries available as well.


The "good old days" is now: Electron makes it easy to make a UI as expressive as you want - responsive, with beautiful animations, with whatever UI elements you'd like - and you don't have to learn anything new - just HTML, CSS, & JS (which all web devs know enough of to get by).


> The "good old days" is now: Electron

This has got to be one of the funniest opening lines, especially in response to visual basic.

I would begrudgingly accept electron if it had the same "open program, click button , draw a button, double click button, write code" experience that VB had


Yes, I definitely want my small GUI app to distribute a gigantic runtime and consume gigs of memory.


HTML everywhere killed professional-looking GUI’s. Web devs generally are clueless about application GUI design and usability. It’s sad.


Web devs: they’re all clueless, they’re all lesser, but for the life of me I just can’t seem to make the UI I want and by gum it’s all their fault.


I think the problem is that devs believe they need to create a unique snowflake app every time, each with it's own special sauce.

Visual basic was different because there was only one way to create a button, so no way to over engineer a new button component. All apps looked the same and nobody cared.


Visual Basic had control styling and the ability to even create custom components as well. For example, I created a textbox control with built-in validation logic in a matter of minutes and was able to drag/drop the control like any other native control onto forms.

I never cared much for VB as a language - but the IDE around it and the ability to very quickly create complex GUI applications was phenomenal.


"The problem" might be that people in this thread and others get frustrated because others have different goals than them.

Of course Electron is overkill for a single-button application. But Visual Basic is absolutely going to be a headache if you want a custom GUI.

Pick the tool that's right for the job!

I build this with Electron: https://videohubapp.com/ Good luck having infinite scroll in a gallery that is butter-smooth using something else (that also doesn't require months of learning new tools) and is cross-platform(!!!).


> All apps looked the same and nobody cared

We actually cared a lot, just in the opposite direction - apps which didn't look the same were weird and bad.


I used to use Delphi over 20 years ago and changed career since.

I'm looking to dabble again. Is there anything similar to RAD these days? It really did make building simple GUIs very easy.


I would say that GAMBAS is the most similar thing I've seen so far (https://en.m.wikipedia.org/wiki/Gambas)


Thank you, I've never seen this before, looks interesting and suit my needs.


Lazarus on FreePascal


Making a GUI these days that isn't based on HTML and CSS in some way is an... experience.


Making a GUI that is based on HTML and CSS and JS is also an... experience.

I have some (ancient) experience in RAD. Once per year I try picking up React/Vue/Angular or whatever is the current fashion, but I get stuck. It's just so _insane_.


I'm working on a project and have been thinking along the same lines. Are there any modern cross-platform tools any language that are good for building like the good old days?


I like to use GoVCL [0] as it provides the GUI of Lazarus [1] including drag-n-drop form designer but with Go as the main language.

GoVCL's author built a C library called liblcl [2] which is what GoVCL uses to control the GUI, so if you know C you can use it instead of Go.

I'm building a lightweight Steam chat client with GoVCL so that I don't need the official client that takes like 200-300mb ram just to show text [3].

[0]: https://github.com/ying32/govcl

[1]: https://www.lazarus-ide.org/

[2]: https://github.com/ying32/liblcl/blob/master/README.en-US.md

[3]: https://files.catbox.moe/c4lzxb.png


Lazarus with Free Pascal is the only one I know of. The designer component works just like VB/WinForms but works cross platform.


I'm a big fan of using wxPython instead of Qt or the other recommendations in OP.

https://www.wxpython.org/

wxWidgets is mostly licensed under an LGPL analog with linking exceptions intended to permit distributing binaries under any license you choose. No part of wxWidgets, including wxPython, has a license more restrictive than the LGPL.


I have tried wxWidgets and wxPython, and while there are many nice features, my issue with it has always been that its behavior is inconsistent across platforms. I have found Qt to be much better at delivering the same experience across platforms. Using PySide 2 with the previous version of Qt (Qt 5 instead of the current Qt 6) avoids any licensing issues since PySide 2 uses the LGPL version of Qt 5.


> my issue with it has always been that its behavior is inconsistent across platforms

Isn't that because different platforms are different? This should be a feature. "Cross-platform that feels native", because each platform has a different definition of "native".

IME wxWidgets was always better than Qt or any other of the high-level piles of bloat. For example, its layout system would actually use the platform-native, rendered sizes of components, instead of the native components only being a skin over a secret other layer that has its own input handling (looking at you, Qt/GTK).


> Isn't that because different platforms are different?

To some extent they are; I don't mind having Windows-native-looking widgets on Windows and Linux-native-looking widgets on Linux.

But programmatically, code that is designed to do a particular function should do it the same on all platforms. That's the point of having a cross-platform toolkit. If I end up having to write a lot of platform-specific code to handle quirks, I might as well just ship separate apps for each platform. It's been a while so I don't have specific examples, but that's generally what I remember running into.

Of course a lot of this will depend on what specific things you are trying to do. One item that I do remember having particular issues with was multiplexing network I/O with the GUI--which is inherently difficult because both of those things want to run their own event loop. Qt has a built-in "widget", QSocketNotifier, to bring network I/O events into its GUI event loop, but wx does not, so I had to roll my own, and it took different tricks on different platforms to make it work (and it was still clunky even then). But many GUI applications don't have to do that.


> If I end up having to write a lot of platform-specific code to handle quirks, I might as well just ship separate apps for each platform.

that's weird, wxWidgets' job is supposed to be to handle this for you.

> One item that I do remember having particular issues with was multiplexing network I/O with the GUI--which is inherently difficult because both of those things want to run their own event loop.

The UI always has to run on the main thread, so why not run the non-UI tasks in a separate thread and send events between the two to communicate? https://wiki.wxwidgets.org/Inter-Thread_and_Inter-Process_co...

Or was wxWidgets 3 not out when you were playing with it last?


> was wxWidgets 3 not out when you were playing with it last?

I don't think so, I think 2 was the latest version I worked with.

> why not run the non-UI tasks in a separate thread and send events between the two to communicate?

Sure, you can do that, if you're willing to deal with all the extra complications involved with having multiple threads and coordinating between them. For some applications that's necessary, but in many cases none of the events, either GUI or network I/O, require CPU intensive responses, so you don't need separate threads for performance, and having them all in one event loop makes the code a lot simpler.


> Sure, you can do that, if you're willing to deal with all the extra complications involved with having multiple threads and coordinating between them. For some applications that's necessary, but in many cases none of the events, either GUI or network I/O, require CPU intensive responses, so you don't need separate threads for performance, and having them all in one event loop makes the code a lot simpler.

This is weird. Having the worker thread separate from the UI thread is a good separation of concerns regardless of whether you need the thread for performance or not. I don't remember if wxWidgets 2 even had message passing between threads, though.

I'd invite you to try wxWidgets 3, it seems to have changed a lot (for the better).


> Having the worker thread separate from the UI thread is a good separation of concerns regardless of whether you need the thread for performance or not.

It can be, but it has a cost in code complexity. Sometimes that cost isn't worth paying.

> I'd invite you to try wxWidgets 3

Yes, it sounds like it's worth me taking a look. I have a Python GUI package [1] that right now only supports Qt 5 in its latest version; it would be nice to put wx support back in.

[1] https://pypi.org/project/plib3.ui/


> try wxWidgets 3

Update from my previous post: I took a look at release dates and wxWidgets 3 was available as far back as 2013, so that is the version my comments were based on (wxPython's version 4 series is the latest that's based on wxWidgets 3, that version of wxPython is the latest I've tested with).


for Python GUIs (or "TUIs", or "a screen with colorful buttons and controls I can use with the mouse or keyboard but NOT a "GUI" " if that helps some of the responders to get through the day) I recommend considering a console-based GUI using the excellent Textual: https://textual.textualize.io/

this is the most modern GUI (in a console or not) framework you'll find for Python right now.


I have used React/Preact/React Native/Flutter to build complex UIs. I thought it would be great to use something like this to render TUI and get rid of some of the app complexity for “simpler” one-user apps. I have used it and it is a nightmare when your app gets just slightly complex. Instead of making simple components I ended up traversing the internals of the library. Impressed by some people getting things done with it though.

- CSS, why?! It does not really work like CSS when it comes to positioning things, overlapping and so on. Compared to previous versions where these properties were in a dict or sent in to the component, they are now in either big string blocks or in separate files, removing syntax highlighting and/or locality.

- Cannot easily use debugging such as PDB because it hijacks Traceback and uses async. Maybe fine if you rely on other debugging tools.

- It lacks simple off-the-shelf components such as menu bars, so I built my own, but run into annoying artifacts as mentioned before.

Rich, the underlying rendering library is good, and simple enough. I ditched Textual for prompt_toolkit, and can still use Rich to render things in pt.


Not really a GUI then, though? It's a UI (and from the screenshots, quite nice), but it's lacking the part that makes it "graphical" (which doesn't actually include "colors or borders", of course, we've been able to do those since CGA, and terminals, respectively).


Wow, Textual looks amazing. Thanks for the link.


I lost a year of time on a side-project because of WxPython, I built a shim to allow me to make small tweaks without having to regenerate the python code, and it was barely usable.... then I had to change a list to a drop-down (I think), and it broke everything.

I threw all of that time away, and had it all working in Lazarus/Free Pascal in less than 2 weeks.

Most web based programmers have no clue how badly "modern" tools are compared to the VB6/Delphi era. Everything is worse, except for GIT... GIT is brilliant.

---

Also, my personal wiki of choice is WikidPad, which is distributed as an executable for windows, and works just fine. I can't move to Linux, because it's distributed as source there, and WxWindows made a breaking change to one of their key parameters to dialog function calls, so none of the dialogs work properly, though it does show text. It's effectively read-only and broken as a result.


I'm sure there is a way to fix it on Linux but an interim solution would be to use the windows executable with wine.


For vanilla applications PySimpleGUI is so easy to use: https://www.pysimplegui.org/en/latest/

Personally, if I'm writing software that needs to talk to a human I'll just build a web interface instead of a GUI.


I love gooey: https://github.com/chriskiehl/Gooey

It allows me to quickly slap a GUI on an existing script that accepts command-line-arguments. In the end, I get the best of both world: Discoverability from the GUI, automation through the script, and automatic feature parity between the two.

Downside: Control over the GUI layout is basic, and only "standard" GUI features work, but I never felt limited when using it.


+1 for Gooey. This "auto-GUI" app is a godsend for any script-user seeking to minimize friction. Lately, I've been diving into Ruby (fallen in love with Ruby on Rails) and I'm hoping to come across something similar.


Dope


Note that it's built on top of wxPython. I think a "middle ground" user interface between the commandline and a full-blown graphical environment is a great idea.


I tried to use GTK for a little project at work and I couldn't figure out how to make it look decent.

I ended up making a flask app and launching a browser. It seemed to be 100x easier.

I would prefer to make native GUI apps but it's just so much more difficult.


My suggestion for people experimenting with GTK these days is to take a look at the examples that are being built into "gtk workbench".


I have had the same problem whenever I've tried to use GTK. Qt, which is what the article is mostly based on, has worked much better for me.


It would be nice to have a canonical python GUI framework. Something modern and elegant and flexible. With an intuitive declarative description, quick for simple things but progressivly enhanceable for more complex things. With a friendly license and an active community sharing components, themes or whatever. Reasonanly performant and ideally cross-platform.

All the options fall short somehow, but guess what, its not much better in any other language. The GUI problem is not truly solved.


Still young and new, but definitely modern, elegant, flexible and declarative: https://github.com/fork-tongue/collagraph


The problem remains delivering the app to the customer in my experience, unless something like flatpak can be used cross platform.

Unless picking a solution from the start and testing it throughout, I find that the most challenging.


I have found PyInstaller [1] to work well for packaging everything into a single ZIP file that unzips to a folder with an executable binary and all accompanying files (or even a single EXE file that self-extracts when run, but that increases startup time). It knows how to package PyQt and its associated Qt libraries (or PySide, which I actually prefer) so that they can be shipped with your application.

[1 https://pyinstaller.org/en/stable/


Yeah, PyInstaller is the best thing out there if you need to bundle a complex Python app into an executable, with cx_Freeze not far behind.

But it's still considered challenging when you compare with any other compiled language, where you can get an executable out of the box. I ship Python desktop apps at work and it's remarkable how much code we accumulated over the years just to deal with the "interpreter in bundled/exe mode".



PyInstaller always seems to tick off our org's MalwareBytes, causing it to break in new and interesting ways but only after a good amount of development hours have been sunk into the project. Recently I've been using Nuitka to package python apps. It would be nice if PSF would adopt/develop an official way to do this.


I’ve heard good things about https://build-system.fman.io/, though I haven’t used.


Also had this problem, tried to create exe packages on windows and had endless trouble (although windows apps aren't my expertise). The real killer in the end for me was some windows security feature that would start killing the process, not immediately, but after a couple of startups. It was an internal tool so in the end I used an executable batch script to start the program, that seemed to bypass the problem, but when it came time to add features and make things available for a wider audience I just abandoned the windows gui and moved to a web app.


I'll flip this around and ask (in earnest - not trying to be snarky), if things like streamlit, NiceGui, gradio, etc exist where you can build a web-accessible gui with only python... why would I ever use Qt?


I think that tkinter is "good enough" for most cases that need a GUI in pythonb these days (for more complex stuff you'd better go with either a web app or a compiled language that creates normal desktop apps).

As a showcase I've built two simple utils with python and tk (and pyinstaller):

- https://github.com/spapas/pdfmerger a simple tool to merge pdfs into one

- https://github.com/spapas/pomo ; a simple pomodoro timer


The pomodoro example seems to be updating the UI from a background thread. The TkDocs tutorial [1] advices against this and suggests posting a custom event to the main thread instead.

Using the after or after_idle methods [2] to post a callback to the main thread also works, and seems easier to me since it allows you to pass arguments.

In this particular example, where the background thread is just used as a timer, you could remove the threading entirely if you use after to let Tkinter handle the timer.

[1] https://tkdocs.com/tutorial/eventloop.html#threads

[2] https://tkdocs.com/shipman/universal.html


Thank you for the suggestion I'll update my code to use after instead!


I used wxPython many, many years ago on a foolish project. I am sure it has matured.

But as always, I turn to PEP 20, in particular "There should be one-- and preferably only one --obvious way to do it." Batteries ought to be included. I'm hardly a language designer, but more and more I care less about things like syntax and such, and more about having as much as possible already built out, so I can focus on the particulars of a problem, rather than having to endure a "evaluate a bunch of alternatives" phase for each little thing.

It's a tall order, and a growing one, but I think whatever the next big language is, it will have that kind of focus.


Maybe I misunderstand you, but there is Tkinter if you want a GUI included with Python.


A little bit, yes.

I don't just want something bundled with Python, I want that thing to be the undeniably best choice. I want "batteries included" to mean that I wouldn't bother to look for anything but what came with the language.


Is it just me or do most python GUI options have ugly UI and seem to lack polish?


Some of the new web-oriented ones look a lot better. Streamlit, nicegui, gradio, etc.


Ah sweet. I’ll check those out. Thanks!


My guilty secret is to use Excel for my quick and dirty GUIs. I wrote a library to make that easy if you know C++. https://github.com/xlladdins/xll. People already know how to use Excel so I don't have to start from scratch


PyQT's license is not ideal, and that's why Pyside exists.

https://www.pythonguis.com/faq/pyqt-vs-pyside/


I've been coming in and out of the Python ecosystem for years as it isn't my primary tool but often is a piece of a project or something along those lines. Is it just my limited exposure, or is there a sort of stagnated, low-key 'GUI lib cold-war' going on in the Python space?

Many libraries, and framework-type things seem to have come and gone, while none have really 'taken hold', so to say. Is this the case? And, specifically, what is the big hurdle to a widely accepted GUI library in Python?


Nobody has recommended prompt_toolkit (TUI only) yet, so here I go:

https://python-prompt-toolkit.readthedocs.io/en/master/

I'm working on an interface for an LLM (large language model), and prompt_toolkit seems to be the only library with enough text-buffer features for me to implement everything I want.

It's quite imperative-feeling though. Have to keep references to individual widgets if you want to do anything with them later.


+1 for prompt_toolkit. Good and approachable docs as well.


> Good and approachable docs as well.

For me the docs were barely enough to get started, and completely left out some of the features I'm using (such as the `get_line_prefix` callback); it took me a lot of messing around to figure out how to do what I wanted.

But it was probably worth it, I'd say.


I'll piggyback here for a related question: I need to build some simple UI on top of a few Snowflake tables, to support a small group of users and their quality assurance tasks. Essentially, they verify important metadata and need to fix it in the Snowflake tables when it is incorrect.

Ideally, I can build that with Python. I was thinking of DRF and React (since things like Retool are out of the question) but I'm open to any framework/stack. What is the most simple way to accomplish and maintain this?


Drop React, just go with pure DRF or Flask and use a nice JavaScript library for table edition (https://datatables.net/).


Your description loudly shouts Streamlit to me. The fact that streamlit is owned by Snowflake is just the cherry on the topy, if anything :)

You may want to have a look at https://streamlit.io/gallery


Shameless plug for my own python GUI toolkit: guietta! http://guietta.readthedocs.io/en/latest/

It is built on top of PyQt5. But be very careful if you use conda, because conda decided to rename the PyQt5 packages, resulting in near-irrecoverable env crashes if conda and pip are mixed. In that case, make sure to use conda-forge to install.


A interesting option I haven’t seen mentioned here is Beeware, an open-source (MIT) project with this summary:

“Write your apps in Python and release them on iOS, Android, Windows, MacOS, Linux, Web, and tvOS using rich, native user interfaces. Multiple apps, one codebase, with a fully native user experience on every platform.”

Source: <https://beeware.org>


The guide lists four different GUI frameworks and the comments (so far!) have listed two more.* None of them really have claim to being the good "default" (except maaaaaaaaybe tkinter) and all of the "GUI-knowledge" is fragmented across them. I like Python but whenever I have to make a GUI, I shy away.

* Between starting and finishing this comment, someone brought up a third. Now we're up to seven!


Well I haven't seen anyone mention Flet, which is pleasant (if maybe not all that complete) if you have Dart/Flutter experience, so increment your counter at least one. :-)

https://flet.dev/


First time I've seen this, looks really cool! Thanks for sharing it!


was about to mention this, I plan to also try a small project in flet to see how it works. I have done flutter/dart before, but was not so enthused about the dart experience.


Both PySide and PyQt are Python wrappers for the Qt library (that makes it 2 frameworks). Basic usage is almost the same.

It seems the author push for PyQt a bit, even though PySide has the same basic capabilities with the benefit of LGPL license (PyQt is GPL or Commercial).


I have been looking at Python GUI libraries/frameworks/services over the past > 1 year. I'll cut straight to the chase with my recommendations for what they are worth.

- NiceGUI https://nicegui.io/#features - my favorite of the bunch, essentially wraps Quasar Vue components with accessible python. Tons of features including SPA, FastAPI under the hood, TailwindCSS. Have used it on a few projects and started contributing recently.

- Streamlit https://streamlit.io/ - if your goal is to get some python code set up with a GUI and deployed ASAP this is the best option. I have gone from 0 to a full working app in like an hour for some projects. Lots of love for it. A bit limited in terms of full-scale applications and large backend databases but it actually holds up really well.

There are a lot of other ones that people regularly recommend.

- Gradio https://gradio.app/ - really popular with huggingface and ml folks. Similar to streamlit in that it sacrifices some level of depth for speed of standing up projects.

- Textual https://www.textualize.io/projects/#textual - Building text-based UIs for the console. Seems to be pretty popular on reddit... Not to be a hater, but I have never seen a good argument for why it's worth dumping a bunch of time into this versus a web-oriented framework. They say "it's useful for products that don't need the internet", "you can use it through ssh", etc... doesn't really fit with my needs, I'll just leave it at that.

- Anvil https://anvil.works/ - a "low code" option for building python GUIs. I am pretty impressed, it has integrated databasing and a lot of plugins. If you are aiming for a scalable application for a large number of users this is probably a good options. My personal gripe with it is the number of mouse clicks it takes to do stuff but that could also be my lack of experience with the tool.

- Plotly dash https://dash.plotly.com/ - not usually thought of as a full GUI library necessarily but they have options for deploying the dashboards to the web - and the overall look and feel is nice. A good option if you have a small notebook with plots that needs wider accessibility.

My use cases are typically 10 - 50 users in an enterprise setting, so accessibility/low barrier to entry (pretty much meaning web-based) are concerns of mine. I also lean toward wanting to avoid learning overly-opinionated libraries (I put Qt and tkinter into this category). Why spend 50 hours learning Qt's way of building an app when I could use something like NiceGUI which lets you build a nicer looking app and gets you familiar with web dev concepts in the process. Imo a better use of my time.


if i was to make a text adventure in a GUI which would be the best one, would you say?


Anyone has some experience with Kivy [1]? It seems that it checks off some of my requirements, like cross-platform, supporting touch interfaces, ease of development, allows complex/fancy UIs as well, etc.

[1] https://kivy.org/


Many of the Python GUIs here are GPLv3, which unfortunately makes them a nonstarter in a lot of projects.


Why should anyone care about that?

If you want to sell something and keep it all to yourself, then go buy something. Qt will happily sell you a quite nice resellable component. If you want to reshare that which you got for free yourself, great, no problem there either.

Say what exactly is the problem that isn't either of those two situations out loud.


Because I want to write open-source software that isn't required to also be GPLv3 as a result of using GPLv3 software.


The problem is when you want to create a tool for internal company usage.


If you don't distribute it publicly, you don't need to distribute the source: https://www.gnu.org/licenses/gpl-faq.en.html#NoDistributionR...


There is no problem with that.


The best Python GUI, Electron, is missing from this page.


Confirmed! You can run Python with Electron:

Use zeroRPC - https://www.zerorpc.io/

https://medium.com/@abulka/electron-python-4e8c807bfa5e




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: