Hacker News new | past | comments | ask | show | jobs | submit login
PyQt5 Tutorial: Create a Python GUI in 2018 (fman.io)
505 points by mherrmann on Sept 25, 2018 | hide | past | web | favorite | 196 comments

We use Qt heavily at Starsky Robotics. We initially used it because it has tight integration with ROS via RQT [1], but I'm pretty impressed with the framework in general. Lots of great tools out of the box, QtCreator is awesome and once you get the right signal/slot model in your head everything is a breeze. Plus getting to prototyping in python is always fast!

For our use case, relative speed of the GUI isn't a factor. We've considered moving to electron just for ease of development, but python is winning out.

[1] http://wiki.ros.org/rqt

What's the memory consumption of pyQT compared to electron apps?

For a JavaScript alternative to pyQT I recommend proton-native[1] - a React environment for cross platform native desktop apps.

1: https://github.com/kusti8/proton-native

I can't comment for pyQt. But the regular C++ Qt app I'm tinkering with at the moment uses 11MB private and about 50MB in shared memory for displaying a simple window with some nested widgets and scrollable lists.

for reference, the app I'm working on (https://ossia.io), a multiple-hundred-LOC Qt-based DAW with support for many network protocols and which uses most Qt libraries as well as boost uses itself 41 megabytes of RAM (private working set) and 70 megabytes total (working set) with a small document loaded, according to the windows task manager.

/me cries in electron

An order of magnitude lower. I see 40Mb on macos right now for a simple app.

I see a simple electron app using 140MB total. Measured by running 'free -m' before and after starting the app and waiting a while for a gc to run.

Measuring memory use is difficult.

FYI, you can open dev tools in electron and manually trigger GC [0].

[0] https://i.imgur.com/JbWArmR.png

I'm sure opending dev tools will increase memory use significantly though. So it's a bit self-defeating. :)

Perhaps there's some API to call instead.

I don't know off hand, and we never compared w/ Electron, it was just floated as an idea. When we eventually fully refactor our GUI code to be agnostic of ROS we'll profile more completely.

I'm presenting QGIS-ROS at ROSCon this year. It's a QGIS plugin for integrating real time robot data. Was relatively easy to do thanks to QGIS being Qt 5.

Felt exactly like making a RQT plugin.

Thank you for not using Electron.

All of our end users are internal, so the main bloat-related problems wouldn't really be an issue at all. Why should we be worried about electron in the future?

I have 3 "internal" tools in electron I need to have running all the time on my PC... It's a corporate dell mini PC, poor thing.

Electron is notorious for disregarding all platform conventions, being slow, and being a memory hog.

The worry is that you have too many developers who don't consider HTML/CSS/JS a proper stack for a "real" engineer and there refuses to learn it.

> even though the development time is obviously shorter with electron

Evidence? I think you're making a great point (about the reputation of html/css/js) but leave the unfounded claims out and your point would be stronger.

Obviously shorter to people who have done HTML/CSS/JS for some time, same with Qt/C++ or Qt/Python.

this. I was just about to write that the tutorial should be shown to every Electron developer.

This is a case where the "in 2018" in the title is very helpful, as Googling information about Python and Qt usually returns something dreadfully out of date. (and as other comments note, there are lots of new companion tools/competitors like Electron)

The API still looks messy and unpythonic though, sadly. Look at the basic hello world example. Why do I need to pass QApplication an empty array? Why am I calling a method ending with _ to launch the program? And the fact the label magically attaches to the app through some side effect is also confusing.

Does anyone know if there's any good shim/wrapper around PyQt that has a better API?

Maybe it's not pythonic but I can assure you, after having passed 6 years working with it that it's extremely efficient and very well integrated with python. It just works, and a complaint about aesthetics won't change that :-)

I second that. Maybe the interface isn't very Pythonic, but it's very Qt-ic, if that's a word. The behavior of PyQt hews closely to the behavior described in Qt's excellent C++ documentation. Furthermore, PyQt lets you do things that you may take for granted, like connecting signals to Python functions and subclassing Qt Widgets. And not only can you subclass a Qt Widget, you can override its methods. Also, you can send a Python str to any method that accepts a QString. I could go on and on about how the boring stuff stays pleasantly boring.

Having used much worse Python bindings for other C++ libraries, the degree to which PyQt just works without blowing up in your face is itself pretty astonishing. Add to that the maturity and depth of the Qt Widget library, and the result is a real pleasure to use.

My first foray with Qt was also my first (serious) foray with Python, so it was easy for me to ignore pythonicity and just write something that approximately resembles Qt's existing style.

Knowing some of my coworkers, though (who use Python daily), I can understand why it'd be jarring.

The now-official bindings (Qt for Python as mentioned in the article) has a waaay more Pythonic API. I actually liked it. The advantage of PyQt5 is that you can look up the Qt documentation.

Qt for Python and PyQt5 have almost exactly the same API, to the point where it took me 30 min to migrate my 15kLoC project [1] from the latter to the former, mostly by changing a few imports. Maybe you meant something else?

1: https://fman.io

Had a very similar experience a few years back migrating from PySide to PyQt when PySide wasn't able to keep up with Qt. Fixing the imports took minutes and we were off to the races.

hmm, then Pyside2 API must have changed significantly. I only used Pyside 1.

Since Python 3 you can use exec() instead of exec_() (in Python 2 exec was a keyword).

> And the fact the label magically attaches to the app through some side effect is also confusing.

Are you referring to the first "label.show()" example?

Typically that pattern is rare (~once per app for the main window). Regarding attachment to the app; QApplication is a process-wide singleton. All objects belong to the same app.

Thank you for the explanation, and the keyword issue makes sense.

Not exactly what you're asking for, but QtPy - https://github.com/spyder-ide/qtpy - is a nice abstraction layer that sits between your program and either PyQt5 or PySide2.

The confusion will go away if you learn how things work under the hood(you should know what an event loop is, learn about Qt widgets parenting, signals and slots, layouts),also in practice you use the GUI tools to create and modify GUIs though you need to learn how to use them properly and not create absolute positioned layouts.

Just to note, there are official [1] Python bindings available for Qt and this can usually be installed with `pip install pyside2`.

[1] https://www.qt.io/qt-for-python

These aren't mentioned until the fourth paragraph of this tutorial. :)

We use (and pay for) PyQt5 at work. Do you have experience with both and if so can you comment on any tangible differences?

If possible, I would rather get behind the "official" one since we also already pay for commercial Qt licenses.

Signal connection behaviour seems to be different in PySide2 regarding non-slot receivers.

E.g. this works in PyQt:

    def f(): pass

But the disconnect fails in PySide2 (RuntimError: not connected). Seems like you have to store the connection object, which is a bit of a PITA because signal.connect() does not return that.

PySide2 is now out of beta?

Yes, it's called "Qt for Python" now

It's still just a "technical preview", but I've been using it for a while and didn't have any problems that weren't caused by me not knowing how Qt works.

Some of the examples in the documentation are still in C++, but it's pretty easy to translate them to Python since the names are the same. (Sometimes painfully so, e.g PySide2.QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOff.)

Agreed. I dabbled with Pyside2 recently and it was refreshingly well structured compared to PyQt4, which is what I last used when I built a GUI a few years ago. It looks like the community might finally get behind one, good, open library for Qt5.

> Some of the examples in the documentation are still in C++

If you do anything serious with Qt you'll have to read those anyway, I believe even PyQt stopped "translating" the docs to python. It's easy enough anyway, even for people like me with no real experience of C++.

There are some things that are still missing and I have to pull from the PyQt5 package, but otherwise it's great.

I wish all the effort to make Qt available in Python was going in to exposing a C API. I of course know this is difficult due to Qt relying on OO extensibility in many cases and I am aware of many efforts in many languages that just use the C++ API directly by essentially building their own C API layer.

That I have to choose between C++ or Python makes it very difficult for many use cases in other languages. What essentially ends up happening is you create the UI in C++ then build a communication/bridge layer with your Go/Rust/JVM/etc app via C and the respective language's FFI features.

I built a C-layer myself for use with C#.


It worked out nicely.

You can use rust https://github.com/KDE/rust-qt-binding-generator There are Go bindings floating around too

Sure, I am familiar with them all (there's another decent Rust cpp gen one too). That's what I was alluding to with "I am aware of many efforts in many languages that just use the C++ API directly by essentially building their own C API layer." Unfortunately each binding has to do this themselves because there's not a blessed C API.

The hardest problem in this space is not writing the code, but packaging the app. All the freeze utilities have their quirks which ensure no one solution works for all three OS consistently.

Even Dropbox had to rewrite their packaging to ensure maximum system compatibility (https://news.ycombinator.com/item?id=18067784)

I created https://build-system.fman.io to help with this exact (general) problem.

whoa... this is so cool. And its based on QT. What do you think of the Dropbox article ?

I wish fbs had already existed when Drew Houston started Dropbox ;)

I've been using wxPython for many years, and it works very well. What are the advantages of PyQT over wxPython? Anyone experienced both 'worlds' in a non-trivial application?

1. wxPython has inconsistent looks and layouts between platforms and monitor resolutions (or DPI). For example, on PlayOnLinux GUI app I cannot click an "OK" button while using Surface Pro because the button is hidden outside of the window.

2. QML is an amazing language. It is modern, declarative and reactive but still very simple to use. Personally I don't want to go back to the traditional GUI coding styles after experienced QML.

3. Qt Designer is a great GUI tool that you can quickly prototype a GUI app.

4. Qt has the best documentation among cross-platform GUI frameworks.

5. Qt is a much bigger framework having more features. For example, you can easily embed WebKit or Chromium very easily.

The article doesn't mention QML at all. Is it possible to use it with Python?

Of course.

Is number five true? (Genuine question.) I haven't used QT in anger, and it's been a few years since I last wrote something in WXP. But the last project went with wxWidgets because of its built-in support for things like drag-and-drop negotiation, (multiple) file type association, undo, print, file preview, system level common accelerators and OS defined accessibility settings (including color and font remapping, speech to text, keyboard navigation, and screen readers). In my mind they are more important than the widgets for building a practical tool. Is QT on par with those?

To join in this comment thread's Electron-ragging, I often find it frustrating that the hard-won OS idioms of the last 20 years have been left so easy to jettison in the age of apps.

Qt has tons of stuff, as far as I know everything you mention is covered pretty well (well, I don't know about speech, but widget text is very accessible).

QT is basically one of two toolkits that most Linux desktops are built on: it has to be wide-ranging enough to cover everything a desktop does, be accessible, and it has to interoperate with "the other" toolkit (GTK). It's absolutely nothing like Electron.

Can vouch that wxPython's documentation is very lacking even from my limited use experience.

The reason why I chose PyQt over wxPython was the former's support for custom styles. I wrote an article with my thoughts on picking a GUI framework [1], in case you're interested.

1: https://fman.io/blog/picking-technologies-for-a-desktop-app-...

I am super happy that you seem so dedicated to providing a good UI library in an attempt to keep people off of Electron (I find one of the biggest hurdles to be the ease of getting started/iteration speed).

Dumb question time: Is this also usable with QML?

You can use PyQt5 with QML here is a simple application https://github.com/siecje/qml-testing

PyQt5 is really great. I wish I could convince some of my co-workers at SNC to use it instead of random solutions ranging from a full-blown WPF app, hand-rolled win32, heavily customized imgui, vt100 over telnet (apologies on behalf of *), to... 5000 lines of AutoIT for a simple gui... smh. I mean we already use python for some build steps. They seem to not be able to get over the python stigma, which I don't think needs to exist, or the pythonic paradigm "breaks their brains."

In commercial settings, I wonder how hard it really is to package this up? I've been building/distributing fully cython'd installers for a while (to sort-of hide the source as well as make a convenient package)... I wonder if that would be harder with PyQt for some reason?

"In the Python world, the process of turning source code into a self-contained executable is called freezing. Although there are many libraries that address this issue – such as PyInstaller, py2exe, cx_Freeze, bbfreze, py2app, ... – freezing PyQt apps has traditionally been a surprisingly hard problem.

We will use a new library called fbs..."

click to fbs...

"You can use fbs for free in open source projects that are licensed under the GPL. If you don't want to open your code up to the public, you can purchase a commercial license for EUR 249 per developer"

I'd happily pay the 250 euros but I somehow doubt fbs will also convert my code to C and compile it.

http://nuitka.net/ is what you are looking for.

It's robust, proven, does work well with C extensions (including numpy and QT) and produces stand alone binaries. You can produce binaries for Windows, Linux and Mac (but not cross compile). It works by turning the whole Python code into C before compiling the result. The additional benefit of that is that you gain a bit of execution speed.

The project is amazingly little known in the community while PyInstaller, py2exe, cx_Freeze, bbfreze, py2app are: nuikta works better, handle more edge cases, target more OSes and support recent versions of Python.

The best way to be convinced is to read the last entry of the blog on the home page: the guy is meticulous with this project.

Well, on my last project, I found PyInstaller to work best and Nuitka changed too many things about the environment.

PyInstaller felt quite close to an auto-unzipping python interpreter and your code, simple.

I can't speak for fbs (never used it), but the way these things usually work (pyinstaller et al) is by compiling everything to .pyc or .pyd and/or pack it up with the python runtime in an executable. It's probably not too hard to extract the original source, but it would be enough to deter a casual observer.

The problems with packaging PyQt usually boil down to module discovery, because the import machinery is leveraged by the wrapper in nontrivial ways. PyInstaller has been ok for me recently, whereas cx_freeze was unpredictable across minor versions.

Ok, thanks for the info! Yeah the pyinstaller, etc. experiences I've had were trivial to decompile from pyc back to py so for "hide the source" we found that Cython takes it to the next level.

I wonder what fbs does in this case that handles the PyQt import stuff so well.

I expect it's a lot of special-casing you can do if you expect Qt to be in the mix.

Do you use any particular lib for your cythonization, or is it all custom ?

I'm sometimes considering porting the UI of a relatively complex management app I wrote sometime ago for a small company, from Ext JS to a Python-flavored traditional GUI framework like PyQt (it would essentially become a desktop app powered by an already Python-based backend, which wouldn't be really a problem deployment-wise, as it's an internal-facing app). I think there would be some benefits, but what stops me is a relatively concrete consideration: the primary UI widget on which my app relies are complex data grids, which must support a lot of functionalities (sorting, filtering, etc; which is an area where Ext JS clearly shines), and I'm wondering which framework would offer the best support (in terms of both functionalities and abstractions) for this kind of needs. Any ideas about this?

You can do all those (sorting, filtering, etc) in Qt as well using the Model/View components. There is a bit of a learning curve to understand the "Qt way of doing MVC", but after that it works fine.

At work we use Qt5 with both C++ and Python (through PyQt) and I love it.

yep, Qt (Pyside) is very mature and very stable. In a professional, long term context, it's totally decisive.

Thanks! What I'd like to know more specifically is if there are some ready-made components already packing a lot of these functionalities without needing too much custom logic, or you need to roll out your own from low-level ones?

QTableView supports pretty much everything. Model proxies like QSortFilterProxyModel give sorting and filtering on models not supporting it natively (at a performance cost, i.e. keeping sorting columns in memory).

The model/view components scale to ~infty items, if the model is correctly implemented. They also support lazy loading.

I'd like to take this time to introduce a project I have been working on. I'm using it in production currently.


It is a perfect balance between QML and .NET. The tech stack splits along the perfect line. QML for UI, .NET for business logic.

I'd be glad to answer any questions.

How do things work regarding the boundary between .NET and Qt memory management? What was the hardest problem you faced regarding this issue (resource leaks, etc.)?

Do you know if it is working fine with F#? Will possibly try it as I learn F# (on Linux).

It does. Any .NET language.

I'm using PyQt for a project right now, and overall it's a nice feeling as always. The model/view classes are great, once you get the hang of them. There are a lot of utilities for things like persistence and threading (but I wouldn't cross the streams with python threads), and it's all crossplatform and very mature by now, the only issues are usually around packaging. QML is also very powerful, but I'm usually happy with Designer -- I guess I'm old-school.

If you need some help with PyQt development, call me up, I'm cheap ;)

> (but I wouldn't cross the streams with python threads)

You can't. Also keep in mind that Python's thread-local storage only works with the threading module threads, not Python threads created elsewhere (e.g. by the "outer" C++ application itself or by a QThread wrapper). It's really quite poorly implemented there IMHO.

The "threading" functionality in Python is a significant downside to the language. I don't know why they went with the idea that people don't need real threads like they can get in C/C++, Java, C#.

> I don't know why they went with the idea that people don't need real threads like they can get in C/C++, Java, C#

Well, for one reason, the choice for Python (or the implementation we now call CPython) was made when you couldn't get what you think of as "real threads" in C/C++, and Java and C# did not yet exist.

Like many engineering choices, there are tradeoffs. The choice to implement Python memory management with reference counting and thus a global interpreter lock was made in an era when garbage collection was much less advanced, when most C libraries were not thread safe, and multi-core CPUs were mainly large computer installations.

As the stack overflow post https://softwareengineering.stackexchange.com/questions/1868... describes, there are advantages to an interpreter lock.

Now you know why.

But the world has changed in ways that make the disadvantages much more prominent. Unfortunately, efforts to remove it have failed because they slow down single-thread performance (which remains quite important) or break backward compatibility, etc.

Python threads are real (operating system) threads.

Note that the "threading" and "_threading" modules wrap thread creation and otherwise just use interpreter C APIs. Their design flaw is that they assume that they are the only ones using the interpreter API.

I assume parent is referring to the GIL, which limits the performance benefits you get from threads.

Oh I know, sometimes I just like being pedantic.

I recently went through almost the exact same exercise (use PyQt5 to write a desktop program that would wrap our warehouse management system's web interface with QtWebKit and - upon receiving a specific download - call out to the REST API for a separate shipping system to book a shipment and print the shipping label). I was developing on Linux (I use Slackware day-to-day), but the pack stations at our warehouses run Windows 10, so it needed to be cross-platform.

The Linux side was surprisingly painless, but getting the Windows side going was a nightmare; none of the traditional options for creating a standalone Windows executable actually worked, and I ended up resorting to installing MSYS2 on every machine, then packaging the app for MSYS2 (and pulling in all of Qt5 as a dependency, meaning that it takes up multiple gigabytes of space for what should be a pretty simple desktop app).

I didn't know about fbs. I'm gonna try it out tonight. The fact that it seems to require resulting apps to be under the GPL is unfortunate, but that's already the case for PyQt5, so whatever.

How is the experience of other folks here? I have found QT as true nightmare. The UX created with QT just doesn’t scale with 4K displays and framework is just pain to maintain on OS like Windows. I rather prefer UX frameworks that uses web technologies any day.

I run Linux without desktop environment on a 4K screen, so I ran into this stuff on all GUI kits. I set the respective scale detection/factor variable in my environment and be done, e.g., for QT5 it'd be:


for auto scaling. See: https://blog.qt.io/blog/2016/01/26/high-dpi-support-in-qt-5-... and https://wiki.archlinux.org/index.php/HiDPI#Qt_5 for more options and other UI kits.

Normally, the desktop environment should do this for you, though. But yeah, this was quite horrible for me for a long time and only got better recently (~ 1 to 2 years), with an wider adoption of high DPI screens, I'd guess.

Still using tkinter here which is python's default GUI, what's the license for PyQt5? For me learning Qt in general is another big investment of limited time, so far I have been using tkinter with python and it works well.

PyQt is GPL or commercial.

Pyside/"Qt for Python" is LGPL.

You then need a license for QT, which is LGPL or commercial. You can use the LGPL version of Qt with commercial PyQt, but I never understood the hoops you might have to jump through in order to comply with the LGPL. Packaging python apps is painful enough without having to worry about that, might as well spend a little to avoid the aggravation. LGPL Qt also lacks a few advanced packages.

PyQt5 is dual licensed GPL / commercial. I.e. free if your work is GPL, pay if your work is proprietary.

PyQt5 is GPL; PySide2 is LGPL.

Do note that the PyQt5 authors (Riverbank Computing) have made it explicit that their view of GPL linking (a matter of debate in some circles) is that you can use PyQt5 from MIT/BSD/... applications.

Thanks for sharing this! I'm close (hopefully) to finishing an app using PyQt5 and the fbs library will be super helpful :)

Cool! Let me know if I can help :-)

I've been using a lot of Python GTK via gobject introspection lately. It works fine, or at least a well as GTK ever works. Why would I want to switch to Qt?

1) I like how GTK and Python object lifetime tracking are compatible (both are simply reference counted), where as Qt has this hierarchical model that feels weird in Python and that led to random segfaults when I tried using PyQt for a serious project last year.

2) gobject introspection works with a variety of different bindings and libraries and provides an object model extensible in any language. Last time I looked at Qt bindings, they looked more like pre-gobject-introspection Python GTK bindings, meaning they were fixed-function and frequently left out some functionality. With gobject, all language bindings are first-class citizens.

How does the reference counting work in the presence of reference cycles involving both the GTK side and the Python side, e.g. an event handler having a reference to an object that has a reference to the object the handler is attached to?

Do they get collected properly, like they would with pure Python objects, or would you have to break up the cycle?

> Why would I want to switch to Qt?

Because GTK is awful outside of Linux.

I'd argue GTK is awful inside of Linux because of client-side decorations (removal of the standard title-bar) that you cannot disable, removal of the menu bar, and the mobile/tablet first design (some people do use desktops and I'm not allergic to text).

> that you cannot disable

I'm pretty sure you can. I like them in most cases, though, just wish they'd gone the Windows/MacOS way of slowly intruding/overlapping a bit occasionally instead of reinventing the whole bar.

Is it? Why? Works fine for me.

Functionaly it is fine, but its sure doesnt look native on Mac OS or Windows.

Qt looks at least a magnitude better (more native) on those platforms

> If you use the Windows style instead, then it looks as follows:

note that this theme is generally not used anymore, being superseded by the WindowsVista one which uses native theming info from windows to render the widgets.

Also see PyOtherSide, a QML plugin that gives asynchronous access to a Python3 interpreter. It let's you use the Qt deployment tools and deploy it like any other Qt app.


Why aren't more desktop apps written with Qt? https://softwareengineering.stackexchange.com/questions/8868...

I like the tutorial, but I don't know why you would use PyQt these days. Tkinter is more permissive and has wrappers like appJar which make it disgustingly easy to put together a quick, ugly GUI. If you're building a desktop app that needs to really look good and be fast, why are you using Python?

> If you're building a desktop app that needs to really look good and be fast, why are you using Python?

Why not? For an app to feel fast, you need to make it responsive and non-blocking. You can easily make apps with Python and Qt or Gtk that start instantly and never seem to hang. Discipline when it comes to not running things on the main thread, using proper async techniques etc. is more important than the number crunching ability of your programming language.

And when you need raw speed, you can easily drop in some C++ code with SWIG for example. For example, I made a GUI for controlling an experimental sensor system. The GUI could look boring, but should be rock solid and always responsive, it should be easy to add new features, and it had to read data from PCIe at hundreds of MB/s or even faster. So I wrote the GUI in PyQt, the PCIe part in C++. Python allowed me to mock the hardware code out easily so I could test the GUI separately, and made it really easy to read configuration files etc. which is unneccessary painful in C++.

> more important than the number crunching ability of your programming language

I work on a data visualization program written with PyQt. As an example, in a scatterplot with several hundred thousand rows, the bottleneck is not number crunching. Numpy could go up another order of magnitude. Probably two. The bottleneck is figuring out efficient ways to display all of the points, correctly, and make them pickable.

Agreed! Although I use SWIG on my job, pybind11[0] is a nice alternative that I've been looking at.

[0] https://github.com/pybind/pybind11

I was recently surprised by how non-ugly a Python Tkinter app can look with some effort. Take a look at this:


"Main development of Thonny takes place in Institute of Computer Science of University of Tartu, Estonia."


It's beautiful! Close to the look of Bvckup 2 (https://bvckup2.com/ - cert revoked due to Chrome changes I think) which might be the best looking Windows app I've seen in a long time.

that's an interesting definition of "non-ugly". I would hesitate a lot before making an app that looks like this screenshot public.

well it's a bit old school but it certainly looks functional. If the program under it is good, it's a very superficial comment. If only you'd see my emacs screen, it's unbelievably ugly and somehow, I work with it every day !

I was replying to a post that stated specifically that it was "non-ugly". In 2018, non-ugly means this :

* https://assets.guitar-pro.com/1.3/images/www/guitar-pro-7/ca...

* https://www.awn.com/sites/default/files/styles/original/publ...

* http://www.comptoir-hardware.com/images/stories/_software/am...

it's not what I use myself, being more of an i3/terminal guy, but it's absolutely what the clients want

For me, "non-ugly" means that it uses the standard UI controls and UI theme for the platform in a reasonable way. That's exactly what the screenshot shows. I would describe it as "neat". All your links are the exact opposite of that.

I'm sure someone (and, in particular, their designers) think they look nice. But the thing about looks is that they're very subjective. However, if I'm using some OS/desktop combo, that means I find its UI, at the very least, acceptable. And thus any app that uses native UI look & feel on that platform is also acceptable. I can't say that for many custom-themed apps.

For example, out of your links, I would say that 2 are downright ugly, and the third is tolerable. And I'm not sure what "in 2018" has to do with that.

What's wrong with it?

Why not use python? It’s fast enough for most uses, and with PyQT it looks good enough on top of that it solves most cases rather fast. Sure I can make a solution that runs faster with a smaller memory footprint in Cpp, but my client doesn’t gain any value from me deciding to delay delivery to hit functional requirements they didn’t ask for and don’t need.

I suppose if you are familiar with Tkinter and are happy with how it looks have at it! But there are a ton of things that can be leveraged from Python and Qt separately going this route.

PyQt uses compiled Qt C++ code so isn't really that slow, comparable to how NumPy does it's number crunching. Even if you do find it is slow, you can always come back and branch down to the C++ level when needed, although there are ton of steps you could take to optimize in Python first. There are also all the Qt tools from UI editor and Designer to QML and way more if you really wanna go down the rabbit hole...

What are you suggesting as a really good looking and fast cross platform alternative??

I think the better appearance of Qt cross-platform is the main drawing point (at least it would be for me). If I were to make a cross-platform application, or even just a Linux one, I'd likely use Qt (with Python bindings because that's what I know). I tried using Tkinter on Linux for a simple utility, but I could not figure out the theming or find any matching themes for Ubuntu.

The combination of an interpreted shell with a statically-typed, AOT-compiled core is a time-tested architecture that leads to quick development times and lots of power. Python is a good choice for the former component of this mix, and if you use it, you want to be able to interact with the GUI.

In my research [1] [2] [3], Tkinter was said to be better for basic applications, PyQt better for more advanced projects.

1: https://stackoverflow.com/a/1094530/1839209

2: https://www.reddit.com/r/learnpython/comments/108zfq/tk_or_q...

3: https://www.quora.com/Should-I-use-PyQt-GTK3-or-tkinter-for-...

if you make use of editable tables, then Qt's is really powerful (the delegate thing is super cool)

I've only been a Python dev, and have ended up becoming entrenched in Tkinter. I want to be able to just use another GUI framework for when I finally switch to something else. So, I can see the use.

For me pyqt is just the most convenient to use. It's hard to beat on the "time to code vs quality of the result" metric.

apparently a lot of the normal and terrible problems are worked around using this: https://build-system.fman.io/

What would you use for an app that needs to look really good and be fast?

Really good? Platform-native APIs.

On Linux, Qt and GTK are the platform native APIs.

Qt qualifies then, at least on Linux.

Qt qualifies on any platform, imo.

Unless you use Qt quick which seems to be the way forward, and what many devs with html/css/js background seem to prefer.

Qt widgets look close to native UIs but the feel isn't always the same, especially when you have to juggle with different platforms (all native widgets differ in subtle ways even when their function is the same).

Qt quick has Qt Quick Controls. Confusing naming, basically the same as Qt widgets, but built in Qt Quick (meaning they're themeable).

Agreed, but you can use those from Python, through pywin32 and (for a few rare things that are missing in the former) ctypes.

(If you're on Windows. On Linux, Qt could be considered native. On Mac there is PyObjC. )

Pywin32 to call native apis for GUIs sounds very, very painful. I had a few run-ins with pywin32 and COM automation, I don’t think I could bear the thought of developing a full UI with that sort of hacks. At that point, might as well go C# (or IronPython, if it’s still around) and enjoy the VS goodies.

COM might have its issues, but I meant using the win32gui, win32api etc. modules to call the native win32 C API for UI. That's hardly a hack, and perhaps even slightly less painful than doing it from C. (I'm only using it for some fairly small things, though.)

The original post said

> why are you using Python?

I'm not sure

> Platform-native APIs.

are a replacement for Python?

As someone who works with Windows forms, I'm wondering where the visual designer to place widgets is.

In addition to what the other said, if you use Qt Quick instead of Qt Widgets you get something which is an order of magnitude more powerful than most of the alternatives :

* http://blog.qt.io/blog/2017/07/05/qt-quick-designer-coffee-m...

* http://blog.qt.io/blog/2017/05/24/qt-quick-designer-qt-creat...

Does Qt Quick integrate well with Python?

as much as the other parts of the API I guess ?

If you use the complete Qt installer, you get QtDesigner.

If you use the PyQT-provided wheels and/or you don'want to mess with the whole Qt, then you can separately install QtCreator, which is very simple and embeds QtDesigner.

Looking at a tutorial, it looks like all it does is layout the form for you. That's a shame. Things closer to what the original VB was are sorely missed in modern computing.

It gives you ui for connecting signals and slots and configuring stuff as well, but few people use it. And qt singals and slots model is far superior to VB/Delphi style callbacks or c# delegates, but you have to program for a while to get why.

Also - layouts in VB/Delphi weren't responsive, layouts made in QtDesigner are.

Ahh...responsive layouts in VB, those were the days. Cramming everything into a frame, and looping through each widget to set width to 49% of the frame.....every time they moved/resized the form. It seems a lot more pleasant in my memory that it likely was at the time.

I have some comparison, because I worked with Oracle Forms and qt3 at the same time in my first job. Forms weren't VB, but the principle was the same - everything was set manually.

Once customer bought new monitors and we had to "upgrade" all forms from 800x600 to 1024x768. Took us 3 months. Qt forms worked fine out of the box.

> ui for connecting signals and slots and configuring stuff as well, but few people use it.

I try hard to do that (it saves on boilerplate), but the challenge is always in finding signals and slots with the same precise amount of parameters. Say I trigger a signal with no parameters and I want to connect it to a slot that takes a boolean always with the same value (e.g. a pressed() connected to a setEnabled(bool), where bool should always be True), I can't do that in Designer, it has to be in actual code - a trivial one-liner, sure, but still one more line of technical debt.

(INB4 "ur doing it wrong": yes, I know about clicked(bool), toggled(bool) etc, it was just an example to explain the concept.)

I don't consider connecting signals in xml (via designer) better than connecting them in code. The line is still there, just in different place.

But the UI changes very rarely, and it’s out of the way most of the time; whereas the class method is always in the way in parts of code that could see a lot of day-to-day activity, migrations (py3...) and so on.

On the other hand refactoring is much easier if all your signals are connected in code.

If you want VB/Delphi-style app builder for Python, can I interest you in Anvil (https://anvil.works)? It targets the web, but you write all the code (even client-side) in Python. We've had multiple customers describe it as a worthy heir to Delphi :)

> It targets the web

Thank you, but no. It doesn't fit the philosophy of the system I'd want to include it in.

Here you go: vTcl -- just like Visual Basic 3.0.

Also, you get to use Tcl instead of Visual Basic, so even better !


Visual Basic 6 compiled to actual native code though, while TCL teached me to never use such languages beyond bare scripting tasks.

Even Visual Basic 3's P-Code interpreter was faster than TCL string based one.

What was the last version of TCL you used? These days they have an extremely cunning system involving multiple representations: Being TCL, every value is of course canonically a string, but if you do (eg) integer operations the result will be stored only as an integer until its needed as anything else. And the body of a 'proc' will be compiled to bytecode on first use, so subsequent calls will go much faster. One could even add a specialising JIT to this if you wanted to.

Version 8.x, the ones where bytecodes where introduced (1999 - 2003).

Thing is, if you want to speak about modern TCL implementations, then the comparison needs to be against VB.NET, with its 64 bit SIMD aware JIT/AOT compilers.

Also, modern Tcl can be compiled to machine code to a large degree thanks to TclQuadCode and LLVM.

Interesting I wasn't aware of it, how mature is it?

It is still experimental, but the output code is stable -- most of the work is in expanding its support for the Tcl language.

It's called Qt designer:


Qt Designer

Anybody know if it's easy to reverse engineer or strip parts of the application when deploying PyQt5 apps? Or do you need extra measures to obfuscate the code to protect certain logic?

I've never tried it but given Python's interpreted nature, it is likely pretty easy unless you use an obfuscator. Note that that's true for Java .class files as well. I was really surprised once when I tried to decompile one of my own that I had thought would be safe. You get near-perfect accuracy.

Yeap, it's pretty easy (see: https://github.com/rocky/python-uncompyle6), although note that if you're worried about decompiling, instead of using an obfuscator, using something as Cython or Nuitka to compile your code should not be difficult -- and as a plus your code becomes faster too ;)

If you build the python ecosystem yourself and supply a custom binary, you could probably obfuscate a bit by modifying the compiled bytecode values. Supply only .pyc and maybe modify or not supply the dis module.

Here's a resource that may help: https://devguide.python.org/compiler/#introducing-new-byteco...

This is especially true for Android apk's broken down into .smali files. They can be decompiled and recompiled with ease.

Part of my job used to be the large scale modification and recompilation of Android apps....you'd be amazed how many passwords are floating around in those.

>Note that that's true for Java .class files as well.

Yes. There was a free third-party Java decompiler called JAD some year ago, for example.

Steve Yegge was a true visionary. In 2004 he predicted the massive popularity of (future) Electron:

> web application programming is gradually going to become the most important client-side programming out there. I think it will mostly obsolete all other client-side toolkits: GTK, Java Swing/SWT, Qt, and of course all the platform-specific ones like Cocoa and Win32/MFC


I raise you a Joel Spolski, 5 months earlier: https://www.joelonsoftware.com/2004/06/13/how-microsoft-lost...

“The new API is HTML, and the new winners in the application development marketplace will be the people who can make HTML sing.”

Is there a GoQt5 being worked on anywhere?

I found two Go bindings for Qt:



Both seem to be in active development. Does anybody have experience with either?

I would kind of expect that "in 2018" we'd be using QML and not QtWidgets?

QML is declarative is fine for very simple UIs only. Once you need to start writing any amount of UI logic it gets inconvenient. If you need simply but flashy -> QML, if you need not so flashy but more functional and "standard desktop UI" -> QtWidgets

FWIW, conda is an easy way to get PyQt, too.

Too bad it's only for Python3 and installing both 2 and 3 is complicated. Would be a good program if it supported python2.

There are several tools that make having both python 2 and 3 running trivial. Pipenv and conda are probably the two better ones. On the whole you should probably using one of them even if all your development is done with the same python version


pipenv is dependency management on top of that

What issues are you having? Installing 2 and 3 side by side on most platforms is trivial.

I gave up on QT and decided instead to invest time learning javascript frameworks, which provide a lot more flexibility for creating apps.

Then try QML! You can create Qt apps using JavaScript (it's ES5 though).

Seconded. I got QML running on my pi using EGL (fullscreen without X) and love it.

QML is actually pretty awesome, I got into it through KDE/Plasma widget development. I think it should be possible to get newest JS working using Babel in your build pipeline. I think it makes a LOT of sense in cases where you develop a UI and can't effort to embed webkit/chrome.

ES6 in Qt 5.12

Wow, I just checked it, and it looks awesome! I'm very exited about the next Qt 5.12. Thank you for letting me know.

it's all the way to ES7 in 5.12

You can create custom widgets like some fancy buttons in Qt too but the appeal is to not customize things and let the user platform and theme choice to dictate how things look like.

Qt had layouts years before html got the flexbox and gridbox too so I don't think there is a feature in html that is missing in Qt, Qt also includes QtWebkit if you ever need say to display some html or run some JS so basically you have access to native libraries and to JS/HTML if you need.

Flexibility to do what, though?

I'm genuinely curious: what doesn't Qt offer that a desktop app might need?

I assume learning to build interfaces in Javascript allows you to port that skill to both the desktop environment (via something like Electron) or web environment through a browser.

If only there would be a standard way of doing GUIs in HTML, but if you give the same GUI to be implemented to 10 Web developers you will get really different code, some would write it in HTML and CSS, other would maybe use angular, others would use react or similar, or if the project uses other backend language/frakework you will get different results depending on what PHP,Ruby,.NET,Java framework was used.

In Qt you use the Designer, you need to learn about the layout system if you want to do good UIs, but your GUI is saved in a file and then the c++/python code implements the event handlers and app logic.

Exactly this. Javascript frameworks allow overlap. I'm using the same tools and language to create a UI. Don't get me wrong I like QT apps and still tinker with them periodically. I will probably use them more once Go finds a way to make truly portable UI applications.

I guess that's cool if you mostly do web stuff. But there are tons of developers that use Python/C++ for embedded systems, OS, data science and other things that could make the same argument for Qt.

Why do you think programmers of all people are heavily migrating to Electron based editors like VS Code? Because they like using slow and bloated apps? And I'm not talking only of web programmers, I know plenty of C++ programmers who moved to VS Code.

Oh, I appear to have misread your comment as "why developers move to Electron for their apps".

The reason why developers, myself included, migrate to VSCode is really simple: because it's the best all-around cross-platform IDE right now for many scenarios, and because it has a thriving extension ecosystem to tailor it further. But it is that in spite of being written in Electron, not because of it. If Microsoft announced that it is being rewritten in Qt tomorrow, I'd be ecstatic.

Just to give you an example of what kinds of issues using web tech for desktop-like experience can cause:


(Yes, I'm well aware that they fixed it. The point is that the offending code needed to be written in the first place. A native desktop app using 13% of the CPU to render a blinking cursor would be considered an insane bug to have in the first place.)

Because C++ is not a particularly good language to write large UI apps in.

Also, because QML is still not as good as the rest of Qt. But it's the right approach - a dedicated framework for desktop apps that is not built on things intended for completely different purposes (like HTML), but stealing the good ideas from there, like using a markup language to define the UI tree, and bindings.

Really, what we need is a cross-platform WPF with less fat. HTML is not it - it's cross-platform WPF with more fat, and not optimized for UI.

Because VSCode is a good enough program that fits their needs and the alternative that they were using was Visual Studio? How does that say anything about native frameworks?

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