
PyQt5 Tutorial: Create a Python GUI in 2018 - mherrmann
https://build-system.fman.io/pyqt5-tutorial
======
DanFeldman
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](http://wiki.ros.org/rqt)

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

~~~
vbsteven
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.

~~~
jcelerier
for reference, the app I'm working on ([https://ossia.io](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.

~~~
Thev00d00
/me cries in electron

------
minimaxir
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)

~~~
ehsankia
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?

~~~
wiz21c
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 :-)

~~~
sevensor
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.

------
chaz6
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](https://www.qt.io/qt-for-python)

~~~
cpburns2009
PySide2 is now out of beta?

~~~
yorwba
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_.)

~~~
sleavey
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.

------
kodablah
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.

~~~
rhodysurf
You can use rust [https://github.com/KDE/rust-qt-binding-
generator](https://github.com/KDE/rust-qt-binding-generator) There are Go
bindings floating around too

~~~
kodablah
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.

------
sandGorgon
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](https://news.ycombinator.com/item?id=18067784))

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

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

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

------
kelvin0
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?

~~~
kbumsik
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.

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

~~~
blattimwind
Of course.

------
nofunsir
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."

------
acidburnNSA
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.

~~~
sametmax
[http://nuitka.net/](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.

~~~
etaioinshrdlu
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.

------
cjauvin
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?

~~~
gusmd
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.

~~~
cjauvin
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?

~~~
blattimwind
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.

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

[https://github.com/qmlnet/qmlnet](https://github.com/qmlnet/qmlnet)

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.

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

~~~
pknopf
It does. Any .NET language.

------
toyg
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 ;)

~~~
blattimwind
> (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.

~~~
krferriter
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#.

~~~
blattimwind
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.

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

~~~
blattimwind
Oh I know, sometimes I just like being pedantic.

------
yellowapple
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.

------
sytelus
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.

~~~
tlamponi
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:

export QT_AUTO_SCREEN_SCALE_FACTOR=1

for auto scaling. See: [https://blog.qt.io/blog/2016/01/26/high-dpi-support-
in-qt-5-...](https://blog.qt.io/blog/2016/01/26/high-dpi-support-in-qt-5-6/)
and
[https://wiki.archlinux.org/index.php/HiDPI#Qt_5](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.

------
ausjke
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.

~~~
toyg
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.

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

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

------
quotemstr
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.

~~~
rapsey
> Why would I want to switch to Qt?

Because GTK is awful outside of Linux.

~~~
cpburns2009
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).

~~~
solarkraft
> 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.

------
jcelerier
> 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.

------
throwwwafgk
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.

[https://thp.io/2011/pyotherside/](https://thp.io/2011/pyotherside/)

------
paulcarroty
Why aren't more desktop apps written with Qt?
[https://softwareengineering.stackexchange.com/questions/8868...](https://softwareengineering.stackexchange.com/questions/88685/why-
arent-more-desktop-apps-written-with-qt)

------
Sileni
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?

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

[https://thonny.org/](https://thonny.org/)

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

~~~
wiz21c
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 !

~~~
jcelerier
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://assets.guitar-pro.com/1.3/images/www/guitar-pro-7/carousel/guitar-pro-7-sheet-music@2x.jpg)

* [https://www.awn.com/sites/default/files/styles/original/publ...](https://www.awn.com/sites/default/files/styles/original/public/image/featured/1025132-allegorithmic-integrates-nvidia-designworks-substance-designer.png?itok=t6GFDiwb)

* [http://www.comptoir-hardware.com/images/stories/_software/am...](http://www.comptoir-hardware.com/images/stories/_software/amd-radeon-crimson-oc-ventilation.jpg)

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

~~~
int_19h
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.

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

~~~
jcelerier
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/07/05/qt-quick-designer-coffee-machine/)

* [http://blog.qt.io/blog/2017/05/24/qt-quick-designer-qt-creat...](http://blog.qt.io/blog/2017/05/24/qt-quick-designer-qt-creator-4-3/)

~~~
miohtama
Does Qt Quick integrate well with Python?

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

------
lalos
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?

~~~
mherrmann
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.

~~~
fabioz
Yeap, it's pretty easy (see: [https://github.com/rocky/python-
uncompyle6](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 ;)

------
21
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_

[https://danluu.com/yegge-predictions/](https://danluu.com/yegge-predictions/)

~~~
toyg
I raise you a Joel Spolski, 5 months earlier:
[https://www.joelonsoftware.com/2004/06/13/how-microsoft-
lost...](https://www.joelonsoftware.com/2004/06/13/how-microsoft-lost-the-api-
war/)

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

------
_eht
Is there a GoQt5 being worked on anywhere?

~~~
cristoperb
I found two Go bindings for Qt:

[https://github.com/kitech/qt.go](https://github.com/kitech/qt.go)

[https://github.com/therecipe/qt](https://github.com/therecipe/qt)

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

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

~~~
ensiferum
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

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

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

~~~
dagw
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

~~~
anentropic
pyenv

pipenv is dependency management on top of that

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

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

~~~
usefulidiot
ES6 in Qt 5.12

~~~
kbumsik
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.

