PyQt Tutorial
PyQt Tutorial
PyQt5 tutorial
Learn how you can create a Python GUI in 2024.
This PyQt5 tutorial shows how to use Python 3 and Qt to create a GUI on
Windows, Mac or Linux. It even covers creating an installer for your app.
What is PyQt5?
PyQt is a library that lets you use the Qt GUI framework from Python. Qt
itself is written in C++. By using it from Python, you can build applications
much more quickly while not sacrificing much of the speed of C++.
PyQt5 refers to the most recent version 5 of Qt. You may still find the
occasional mention of (Py)Qt4 on the web, but it is old and no longer
supported.
Install PyQt
The best way to manage dependencies in Python is via a virtual
environment. A virtual environment is simply a local directory that
contains the libraries for a specific project. This is unlike a system-wide
installation of those libraries, which would affect all of your other projects
as well.
call venv/scripts/activate.bat
On Mac and Linux, use:
source venv/bin/activate
You can see that the virtual environment is active by the (venv) prefix in
your shell:
To now install PyQt, issue the following command:
Create a GUI
Time to write our very first GUI app! With the virtual environment still
active, start Python. We will execute the following commands:
app = QApplication([])
This is a requirement of Qt: Every GUI app must have exactly one instance
of QApplication. Many parts of Qt don't work until you have executed the
above line. You will therefore need it in virtually every (Py)Qt app you
write.
The brackets [] in the above line represent the command line arguments
passed to the application. Because our app doesn't use any parameters,
we leave the brackets empty.
label.show()
Depending on your operating system, this already opens a tiny little
window:
The last step is to hand control over to Qt and ask it to "run the
application until the user closes it". This is done via the command:
app.exec()
If all this worked as expected then well done! You've just built your first
GUI app with Python and Qt.
Widgets
Everything you see in a (Py)Qt app is a widget: Buttons, labels, windows,
dialogs, progress bars etc. Like HTML elements, widgets are often nested.
For example, a window can contain a button, which in turn contains a
label.
You can download the code for the app shown in the screenshot here, if
you are interested.
Layouts
Like the example above, your GUI will most likely consist of multiple
widgets. In this case, you need to tell Qt how to position them. For
instance, you can use QVBoxLayout to stack widgets vertically:
There are of course many other kinds of layouts (eg. QHBoxLayout to lay
out items in a row). See Qt's documentation for an overview.
Custom styles
One of Qt's strengths is its support for custom styles. There are many
mechanisms that let you customize the look and feel of your application.
This section outlines a few.
Built-in styles
The coarsest way to change the appearance of your application is to set
the global Style. Recall the widgets screenshot above:
This uses a style called Fusion. If you use the Windows style instead, then it
looks as follows:
To apply a style, use app.setStyle(...):
Custom colors
If you like a style, but want to change its colors (eg. to a dark theme),
then you can use QPalette and app.setPalette(...). For example:
app = QApplication([])
app.setStyle('Fusion')
palette = QPalette()
palette.setColor(QPalette.ButtonText, Qt.red)
app.setPalette(palette)
button = QPushButton('Hello World')
button.show()
app.exec()
This changes the text color in buttons to red:
For a dark theme of the Fusion style, see here.
Style sheets
In addition to the above, you can change the appearance of your
application via style sheets. This is Qt's analogue of CSS. We can use this
for example to add some spacing:
For more information about style sheets, please see Qt's documentation.
Signals / slots
Qt uses a mechanism called signals to let you react to events such as the
user clicking a button. The following example illustrates this. It contains a
button that, when clicked, shows a message box:
button.clicked.connect(on_button_clicked)
button.show()
app.exec()
The interesting line is highlighted above: button.clicked is a
signal, .connect(...) lets us install a so-called slot on it. This is simply a
function that gets called when the signal occurs. In the above example,
our slot shows a message box.
The term slot is important when using Qt from C++, because slots must
be declared in a special way in C++. In Python however, any function can
be a slot – we saw this above. For this reason, the distinction between
slots and "normal" functions has little relevance for us.
Signals are ubiquitous in Qt. And of course, you can also define your own.
This however is beyond the scope of this tutorial.
You could ask the users of your app to install Python and PyQt like we did
above, then give them your source code. But that is very tedious (and
usually impractical). What we want instead is a standalone version of your
app. That is, a binary executable that other people can run on their
systems without having to install anything.
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 that lets you create standalone
executables for PyQt apps. To install it, enter the command:
fbs startproject
This prompts you for a few values:
When you type in the suggested run command, an empty window should
open:
This is a PyQt5 app just like the ones we have seen before. Its source code
is in src/main/python/main.py in your current directory. But here's the cool
part: We can use fbs to turn it into a standalone executable!
fbs freeze
This places a self-contained binary in the target/MyApp/ folder of your
current directory. You can send it to your friends (with the same OS as
yours) and they will be able to run your app!
(Please note that the free version of fbs only supports Python 3.5 or 3.6. If
you have a different version, please install one of these supported Python
versions or buy fbs Pro).
For more information on how you can use fbs for your existing application,
please see this article. Or fbs's tutorial.
Summary
If you have made it this far, then big congratulations. Hopefully, you now
have a good idea of how PyQt (and its various parts) can be used to write
a desktop application with Python. We also saw how fbs lets you create
standalone executables and installers.
Michael has been working with PyQt5 since 2016, when he started fman,
a cross-platform file manager. Frustrated with the difficulties of creating a
desktop app, Michael open sourced fman's build system (fbs). It saves
you months when creating Python Qt GUIs. Recently, Michael also wrote a
popular book about these two technologies.
Michael Herrmann
Omaha Consulting GmbH
© 2016 – 2024
Privacy Policy