The complete PyQt5 tutorial — Create GUI applications with Python

The easy way to create desktop applications

Last updated

Create Desktop GUI Applications with PyQt5

PyQt is a Python library for creating GUI applications using the Qt toolkit. Created by Riverbank Computing, PyQt is free software (GPL licensed) and has been in development since 1999. PyQt5 was released in 2016 and last updated in October 2021.

This complete PyQt5 tutorial takes you from first concepts to building fully-functional GUI applications in Python. It requires some basic Python knowledge, but no previous familiarity with GUI concepts. Everything will be introduced step by by step, using hands-on examples.

PyQt5 is the Qt5-based edition of the Python GUI library PyQt from Riverbank Computing.

There are two major versions currently in use: PyQt5 based on Qt5 and PyQt6 based on Qt6. Both versions are almost completely compatible aside from imports, and lack of support for some advanced modules in Qt6. PyQt6 also makes some changes to how namespaces and flags work, but these are easily manageable.

Looking for something else? I also have a PyQt6 tutorial, PySide2 tutorial and PySide6 tutorial.

This track consists of 33 tutorials. Keep checking back as I'm adding new tutorials regularly — last updated .

Getting started with PyQt5

Take your first steps building apps with Python & Qt5

Like writing any code, building PyQt5 applications is all about approaching it in the right way. In the first part of the course we cover the fundamentals necessary to get you building Python GUIs as quickly as possible. By the end of the first part you'll have a running QApplication which we can then customize.

Creating your first app with PyQt5 video
A simple Hello World! application with Python and Qt5

In this tutorial we'll learn how to use PyQt to create desktop applications with Python. First we'll create a series of simple windows on your desktop to ensure that PyQt is working and introduce some of the basic concepts. Then we'll take a brief look at the event loop and how it relates to GUI programming in Python. Finally we'll look at Qt's QMainWindow which offers some useful common interface elements such as toolbars and menus. These will be explored in more detail in the subsequent tutorials.

Start now Complete

PyQt5 Signals, Slots & Events video
Triggering actions in response to user behaviors and GUI events

So far we've created a window and added a simple push button widget to it, but the button doesn't do anything. That's not very useful at all -- when you create GUI applications you typically want them to do something! What we need is a way to connect the action of pressing the button to making something happen. In Qt, this is provided by signals and slots or events.

Start now Complete

PyQt5 Widgets video
Using Qt5's library of built-in widgets to build your applications

In Qt (and most User Interfaces) ‘widget’ is the name given to a component of the UI that the user can interact with. User interfaces are made up of multiple widgets, arranged within the window.

Start now Complete

PyQt5 Layouts video
Use layouts to effortlessly position widgets within the window

So far we've successfully created a window, and we've added a widget to it. However we normally want to add more than one widget to a window, and have some control over where it ends up. To do this in Qt we use layouts. There are 4 basic layouts available in Qt, which are listed in the following table.

Start now Complete

PyQt5 Toolbars & Menus — QAction video
Defining toolbars, menus and keyboard shortcuts with QAction

Next we'll look at some of the common user interface elements, that you've probably seen in many other applications — toolbars and menus. We'll also explore the neat system Qt provides for minimising the duplication between different UI areas — QAction.

Start now Complete

PyQt5 Dialogs and Alerts video
Notify your users and ask for their input

Dialogs are useful GUI components that allow you to communicate with the user (hence the name dialog). They are commonly used for file Open/Save, settings, preferences, or for functions that do not fit into the main UI of the application. They are small modal (or blocking) windows that sit in front of the main application until they are dismissed. Qt provides a number of 'special' built-in dialogs for the most common use-cases, allowing you to provide a platform-native user experience.

Start now Complete

Creating additional windows video
Opening new windows for your application

In an earlier tutorial we've already covered how to open dialog windows. These are special windows which (by default) grab the focus of the user, and run their own event loop, effectively blocking the execution of the rest of your app.

Start now Complete

Creating applications with Qt Designer

Using the drag-drop designer to develop your apps

As your applications get larger or interfaces become more complicated, it can get a bit cumbersome to define all elements programmatically. The good news is that Qt comes with a graphical editor Qt Designer (or Qt Creator) which contains a drag-and-drop UI editor — Qt Designer. In this PyQt5 tutorial we'll cover the basics of creating Python GUIs with Qt Designer.

First steps with Qt Designer
Use Qt Designer's drag and drop interface to design your PyQt5 GUI

So far we have been creating apps using Python code. This works great in many cases, but as your applications get larger or interfaces more complicated, it can get a bit cumbersome to define all widgets programmatically. The good news is that Qt comes with a graphical editor — Qt Designer — which contains a drag-and-drop UI editor. Using Qt Designer you can define your UIs visually and then simply hook up the application logic later.

Start now Complete

Laying Out Your PyQt5 GUIs With Qt Designer
Use Qt Designer to effortlessly build your application UI

When laying out your PyQt5 GUIs it can be quite a tricky task to place every widget in the right position on your forms. Fortunately, Qt offers a set of layout managers that simplify the process of widget positioning and will allow you to easily create any kind of layout. To lay out the widget in a form, you can create everything in code, or you can create your layout with Qt Designer. In this tutorial, you'll learn how to use Qt's layouts with Qt Designer to build complex GUIs for your applications.

Start now Complete

Creating Dialogs With Qt Designer
Using the drag and drop editor to build PyQt5 dialogs

Most PyQt GUI applications consist of a main window and several dialogs. Dialogs are small-sized windows that allow you to communicate with your users, either by showing messages on the screen or by taking the user's input. You can use Qt Designer to create dialogs taking advantage of the variety of options that this tool offers.

Start now Complete

Embedding custom widgets from Qt Designer
Learn how to use custom widgets in your PyQt5 applications when designing with Qt Designer

Qt Designer is a great tool for designing PyQt5 GUIs, allowing you to use the entire range of Qt5 widgets and layouts to construct your apps. As your applications get more complex however you may find yourself creating custom widgets, or using PyQt5 libraries such as PyQtGraph, who's widgets are not available within Designer.

Start now Complete

The QResource System
Using the QResource system to package additional data with your applications

Building applications takes more than just code. Usually your interface will need icons for actions, you may want to add illustrations or branding logos, or perhaps your application will need to load data files to pre-populate widgets. These data files are separate from the source code of your application but will ultimately need to be packaged and distributed with it in order for it to work.

Start now Complete

Mozzarella Ashbadger

Build your own tabbed web browser with PyQt5

Now we've learnt the basics, we'll put it into practice building a real-life app. In this course we'll create a functional web browser using Qt5 widgets. Starting with the basics and then gradually extending it to add features like opening and saving pages, help, printing and tabbed browsing. Follow the tutorial step by step to create your own app, but feel free to experiment as you go.

Mozzerella Ashbadger video
The first steps building the browser with PyQt5

So far we've learned the basics of building Python GUI applications with Qt. In this tutorial we'll take what we've learned and apply it to creating a custom web browser -- Mozzerella Ashbadger -- in Python.

Start now Complete

Adding navigational controls to a PyQt5 Web Browser video
Hook up QAction signals to web browser slots

In the first part of this tutorial we put together a simple skeleton of a browser using Qt's built-in browser widget. This allows you to open a webpage, view it and click around -- all that is handled automatically for you. But the interface is entirely up to you.

Start now Complete

Open and save HTML in a PyQt5 browser video
Adding file dialogs to load and save HTML

A File menu was added with self.menuBar().addMenu("&File") assigning the F key as a Alt-shortcut. Once we have the menu object, we can can add QAction objects to it to create the entries. We create two basic entries here for opening and saving HTML files (from a local disk). These both require custom slot method.

Start now Complete

Adding application Help and About dialogs video
Put some finishing touches to your application

In the previous parts we've added some basic UI elements, including menus and toolbars, and implemented basic loading & saving of HTML files to the browser view. Now, to complete the standard interface, we will add a Help menu.

Start now Complete

Tabbed web browsing video
Use signal redirection to add a multi-tab interface

In the previous parts of this tutorial we built our own custom web browser using PyQt5 widgets. Starting from a basic app skeleton we've extended it to add support a simple UI, help dialogs and file operations. However, one big feature is missing -- tabbed browsing.

Start now Complete

Extended UI features

Extending your apps with complex GUI behaviour

In this PyQt5 tutorial we'll cover some advanced features of Qt that you can use to improve your Python GUIs.

Transmitting extra data with Qt Signals
Modifying widget signals to pass contextual information to slots

Signals are a neat feature of Qt that allow you to pass messages between different components in your applications. Signals are connected to slots which are functions (or methods) which will be run every time the signal fires. Many signals also transmit data, providing information about the state change or widget that fired them. The receiving slot can use this data to perform different actions in response to the same signal.

Start now Complete

System tray & Mac menu bar applications
Add quick access functions to your apps

System tray applications (or menu bar applications) can be useful for making common functions or information available in a small number of clicks. For full desktop applications they're a useful shortcut to control apps without opening up the whole window.

Start now Complete

Threads & Processes

Run concurrent tasks without impacting your UI

As your applications become more complex you may finding yourself wanting to perform long-running tasks, such as interacting with remote APIs or performing complex calculations. By default any code you write exists in the same thread and process, meaning your long-running code can actually block Qt execution and cause your Python GUI app to "hang". In this PyQt5 tutorial we'll cover how to avoid this happening and keep your applications running smoothly, no matter the workload.

Multithreading PyQt5 applications with QThreadPool
Run background tasks concurrently without impacting your UI

A common problem when building Python GUI applications is "locking up" of the interface when attempting to perform long-running background tasks. In this tutorial I'll cover one of the simplest ways to achieve concurrent execution in PyQt5.

Start now Complete

Using QProcess to run external programs
Run background programs without impacting your UI

So far we've looked at how to run work in separate threads, allowing you to do complex tasks without interrupting your UI. This works great when using Python libraries to accomplish tasks, but sometimes you want to run external applications, passing parameters and getting the results.

Start now Complete

ModelViews and Databases

Connecting your application to data sources

All but the simplest of apps will usually need to interact with some kind of external data store — whether that's a database, a remote API or simple configuration data. The Qt ModelView architecture simplifies the linking and updating your UI with data in custom formats or from external sources. In this PyQt5 tutorial we'll discover how you can use Qt ModelViews to build high performance Python GUIs.

The ModelView Architecture
Qt's MVC-like interface for displaying data in views

As you start to build more complex applications with PyQt5 you'll likely come across issues keeping widgets in sync with your data. Data stored in widgets (e.g. a simple QListWidget) is not readily available to manipulate from Python — changes require you to get an item, get the data, and then set it back. The default solution to this is to keep an external data representation in Python, and then either duplicate updates to the both the data and the widget, or simply rewrite the whole widget from the data. This can get ugly quickly, and results in a lot of boilerplate just for fiddling the data.

Start now Complete

Displaying tabular data in Qt5 ModelViews
Create customized table views with conditional formatting, numpy and pandas data sources.

In the previous chapter we covered an introduction to the Model View architecture. However, we only touched on one of the model views — QListView. There are two other Model Views available in Qt5 — QTableView and QTreeView which provide tabular (Excel-like) and tree (file directory browser-like) views using the same QStandardItemModel.

Start now Complete

Graphics and Plotting

Vector graphics and plotting using PyQtGraph

Python is one of the most popular languages in the data science and machine learning fields. Effective visualization of data is a key part of building usable interfaces for data science. Matplotlib is the most popular plotting library in Python, and comes with support for PyQt built in. In addition, there are PyQt-specific plotting options available such as PyQtGraph which provide a better interactive experience. In this tutorial we'll look at these alternatives and build some simple plot interfaces.

Plotting with PyQtGraph
Create custom plots in PyQt with PyQtGraph

One of the major strengths of Python is in exploratory data science and visualization, using tools such as Pandas, numpy, sklearn for data analysis and matplotlib plotting. Buiding GUI applications with PyQt gives you access to all these Python tools directly from within your app, allowing you to build complex data-driven apps and interactive dashboards.

Start now Complete

Plotting with Matplotlib
Create PyQt5 plots with the popular Python plotting library

In a previous tutorial we covered plotting in PyQt5 using PyQtGraph. PyQtGraph uses the Qt vector-based QGraphicsScene to draw plots and provides a great interface for interactive and high performance plotting.

Start now Complete

QGraphics Framework

Vector graphic interfaces

The Qt Graphics View framework is a scene-based vector graphics API. Using this you can create dynamic interactive interfaces for anything from vector graphics tools, data analysis workflow designers to simple 2D games. The Graphics View Framework allows you to develop fast & efficient scenes, containing millions of items, each with their own distinct graphic features and behaviors.

Introduction to the QGraphics framework
Creating vector interfaces using the QGraphics View framework

The Qt Graphics View Framework allows you to develop fast and efficient 2D vector graphic scenes. Scenes can contain millions of items, each with their own features and behaviors. By using the Graphics View via PyQt you get access to this highly performant graphics layer in Python. Whether you're integrating vector graphics views into an existing PyQt application, or simply want a powerful vector graphics interface for Python, Qt's Graphics View is what you're looking for.

Start now Complete

Custom Widgets

Designing your own custom widgets in PyQt

Widgets in Qt are built on bitmap graphics — drawing pixels on a rectangular canvas to construct the "widget". To be able to create your own custom widgets you first need to understand how the QPainter system works and what you can do with it. In this PyQt5 tutorial we'll go from basic bitmap graphics to our own entirely custom widget.

QPainter and Bitmap Graphics
Introduction to the core features of QPainter

The first step towards creating custom widgets in PyQt5 is understanding bitmap (pixel-based) graphic operations. All standard widgets draw themselves as bitmaps on a rectangular "canvas" that forms the shape of the widget. Once you understand how this works you can draw any widget you like!

Start now Complete

Creating custom GUI widgets in PyQt5
Build a completely functional custom widget from scratch using QPainter

In the previous tutorial we introduced QPainter and looked at some basic bitmap drawing operations which you can used to draw dots, lines, rectangles and circles on a QPainter surface such as a QPixmap.

Start now Complete

Animating custom widgets with QPropertyAnimation
Add dynamic visual effects to your custom widgets

In the previous tutorial we looked at how you can build custom widgets with PyQt5. The widget we built used a combination of layouts, nested widgets and a simple QPainter canvas to create a customized widget you can drop into any application.

Start now Complete

Packaging and distribution

Sharing your awesome applications with other people

There comes a point in any app's development where it needs to leave home — half the fun in writing software is being able to share it with other people. Packaging Python GUI apps can be a little tricky, but in this PyQt5 tutorial we'll cover how to package up your apps to share, whether commercially or just for fun.

Packaging PyQt5 applications for Windows, with PyInstaller
Turn your Qt5 application into a distributable installer for Windows

There is not much fun in creating your own desktop applications if you can't share them with other people — whether than means publishing it commercially, sharing it online or just giving it to someone you know. Sharing your apps allows other people to benefit from your hard work!

Start now Complete

Packaging PyQt5 apps with fbs
Distribute cross-platform GUI applications with the fman Build System

fbs is a cross-platform PyQt5 packaging system which supports building desktop applications for Windows, Mac and Linux (Ubuntu, Fedora and Arch). Built on top of PyInstaller it wraps some of the rough edges and defines a standard project structure which allows the build process to be entirely automated. The included resource API is particularly useful, simplifying the handling of external data files, images or third-party libraries — a common pain point when bundling apps.

Start now Complete

QtQuick & QML

Building modern PyQt5 GUIs with QtQuick & QML

Qt Quick is Qt's declarative UI design system, using the Qt Modeling Language (QML) to define custom user interfaces. Originally developed for use in mobile applications, it offers dynamic graphical elements and fluid transitions and effects allowing you to replicate the kinds of UIs you find on mobile devices. Qt Quick is supported on all desktop platforms too and is a great choice for building desktop widgets or other interactive tools. Qt Quick is also a great choice for developing UIs for hardware and microcontrollers with PyQt5.

Create applications with QtQuick
Build modern applications with declarative QML

In previous tutorials we've used the Qt Widgets API for building our applications. This has been the standard method for building applications since Qt was first developed. However, Qt provides another API for building user interfaces: Qt Quick. This is a modern mobile-focused API for app development, with which you can create dynamic and highly customizable user interfaces.

Start now Complete

Animations and Transformations with QtQuick
Building an animated analog clock in QML

In the previous tutorial we implemented a basic QML clock application using Python code to get the current time, format it into a string and send that through to our QML layout for display using Qt signals.

Start now Complete