Skip to main content
HomeTutorialsPython

Introduction to PySide6 for Building GUI Applications with Python

Learn the basics of PySide6 to build your first desktop application and incorporate data visualizations from popular data science libraries into it.
Jan 2024  · 14 min read

Let’s face the truth: the non-technical stakeholders, or the end users, have no interest in the Jupyter Notebooks or the Python scripts you create as a data practitioner. They want to be able to interact with the solution and see the results for themselves.

This is why we need to transform our work into insights reports, dashboards, or data science applications. While reports, dashboards, and web applications are common, a lesser-explored alternative is desktop applications.

Imagine being able to design an app where users can click buttons, fill out forms, and navigate through menus — all through a clear and pleasant interface on your desktop. How cool would that be?

In this tutorial, we will introduce PySide6, help you with the initial installations, and build your first desktop application. We will also explore the commonly used widgets, incorporate data visualizations from popular data science libraries, and share useful resources.

What is PySide6?

PySide6 is a toolkit that lets you create your software applications using the Python programming language with attractive and intuitive graphical interfaces.

It’s like a set of building blocks for software, allowing even those new to programming to piece together the visual and interactive elements that make up an app. With PySide6, you can turn your ideas into real, functioning applications that work on Windows, Mac, Linux, and even mobile platforms.

Setting up PySide6

For the setup, we assume that you already have Python installed, and have your usual IDE with you. The installation setup is fairly straightforward.

Open your terminal and run the following, and you’ll be good.

pip3 install pyside6

Building Your First PySide6 Application

Now that you have successfully installed the library, the next step is to build your first PySide6 application. This is also a way for us to test whether the setup is working fine while giving you a flavor of desktop applications.

Create a Python file named “main.py” and copy and paste the following code.

import sys
from PySide6.QtWidgets import QApplication, QLabel
app = QApplication(sys.argv)
label = QLabel('Hello, PySide6!')
label.show()
sys.exit(app.exec_())

We will understand the code in a minute, but first, run the Python file through your terminal as follows:

python3 run main.py

Congratulations, you’ve built your first desktop application! You should be seeing something like this:

The “Hello, PySide6” desktop application (Image by author)

The “Hello, PySide6” desktop application (Image by author)

Let’s now break down the simple PySide6 script we saw earlier. We first import relevant modules:

import sys
from PySide6.QtWidgets import QApplication, QLabel
  • sys is a Python standard library module that provides access to some variables used or maintained by the Python interpreter. In the context of a PySide6 application, it's commonly used for command-line arguments. Check out our command line argument parsing tutorial to learn more.
  • QApplication and QLabel are imported from PySide6.QtWidgets. QApplication is the core application management class in PySide6, necessary for any GUI application. QLabel is a widget that displays text, which we use to show a simple message.

Next, we create an instance of QApplication.

app = QApplication(sys.argv)

This is required in every PySide6 application. sys.argv is used to pass command-line arguments to the application. Even if you don't use command-line arguments, sys.argv is still required, as it initializes the QApplication with some defaults.

label = QLabel('Hello, PySide6!')

Next, we create a QLabel widget with the text "Hello, PySide6!". This is the text that will be displayed in our application window.

label.show()

This line makes the label visible. By default, widgets in PySide6 are not visible until you explicitly show them.

sys.exit(app.exec_())

Finally, this line starts the event loop of the application. The exec_() method of QApplication enters the main loop of the application, where all events (like mouse clicks and keyboard presses) are processed. The sys.exit() call ensures a clean exit when the application is closed. The event loop runs until the QApplication instance receives an exit signal, such as closing the window.

As we saw in the output earlier, our script creates a basic GUI application with a single-window displaying the text “Hello, PySide6!”.

Incorporating PySide6 Widgets into the GUI Application

Widgets in the context of PySide6 and GUIs are the basic building blocks used to create a user interface in a software application. Think of widgets as various elements you see and interact with in any software application — like buttons, text boxes, labels, sliders, and drop-down menus.

In the first PySide6 application, we saw a label widget that was used to display text. When building a GUI with PySide6, we’re essentially arranging these widgets in a window in a way that makes sense for our application. Each widget serves a specific purpose and interacts with the user differently.

The comprehensive list of widgets, and their usage can be found in the official documentation, but the most commonly used ones are:

  • QLabel: A widget used to display text or images. It’s often utilized for showing instructions, and messages, or even for displaying images in a GUI.
  • QPushButton: A clickable button that users can interact with to trigger certain actions. It’s one of the most fundamental widgets in GUI development, used for submitting forms, starting processes, and more.
  • QLineEdit: This widget allows users to enter and edit a single line of text. It’s commonly used in forms and settings where text input is required, such as entering a name or a number.
  • QComboBox: A combination of a dropdown list and a text field, allowing users to choose an option from a list of predefined choices or to type in their own.
  • QCheckBox: Presents a box that users can check or uncheck. It’s typically used to enable or disable features or to indicate agreement with terms and conditions.
  • QRadioButton: Designed for selecting one option from a set, radio buttons allow one choice within a group, making them ideal for options like gender, age ranges, or any other exclusive selection.
  • QTextEdit: A widget for multi-line text editing, offering more functionality than QLineEdit, such as text formatting, copying and pasting, and scrolling.
  • QSlider: Provides a slider control, a useful tool for inputting numeric values within a range, like adjusting volume or setting a price filter.
  • QSpinBox: A widget that lets users select a number from a given range. Users can increase or decrease the number using small up and down arrows.
  • QProgressBar: Displays the progress of a task. It visually represents the completion percentage, making it useful for tracking progress in processes like file uploads or downloads.
  • QTableWidget: Useful for displaying data in a tabular format. It allows for the organization of data into rows and columns, making it easier to display and interact with structured data.

Let us create an application that uses these common widgets and displays them:

import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QLabel, QPushButton, QLineEdit, QComboBox, QCheckBox, QRadioButton, QTextEdit, QSlider, QSpinBox, QProgressBar, QTableWidget, QTableWidgetItem, QVBoxLayout, QHBoxLayout, QWidget

class DemoWindow(QMainWindow):
   def __init__(self):
       super().__init__()

       # Main Widget and Layout
       main_widget = QWidget()
       self.setCentralWidget(main_widget)
       main_layout = QVBoxLayout(main_widget)

       # Function to add widget with label
       def add_widget_with_label(layout, widget, label_text):
           hbox = QHBoxLayout()
           label = QLabel(label_text)
           hbox.addWidget(label)
           hbox.addWidget(widget)
           layout.addLayout(hbox)

       # QLabel
       self.label = QLabel('Hello PySide6!')
       add_widget_with_label(main_layout, self.label, 'QLabel:')

       # QPushButton
       self.button = QPushButton('Click Me')
       self.button.clicked.connect(self.on_button_clicked)
       add_widget_with_label(main_layout, self.button, 'QPushButton:')

       # QLineEdit
       self.line_edit = QLineEdit()
       add_widget_with_label(main_layout, self.line_edit, 'QLineEdit:')

       # QComboBox
       self.combo_box = QComboBox()
       self.combo_box.addItems(['Option 1', 'Option 2', 'Option 3'])
       add_widget_with_label(main_layout, self.combo_box, 'QComboBox:')

       # QCheckBox
       self.check_box = QCheckBox('Check Me')
       add_widget_with_label(main_layout, self.check_box, 'QCheckBox:')

       # QRadioButton
       self.radio_button = QRadioButton('Radio Button')
       add_widget_with_label(main_layout, self.radio_button, 'QRadioButton:')

       # QTextEdit
       self.text_edit = QTextEdit()
       add_widget_with_label(main_layout, self.text_edit, 'QTextEdit:')

       # QSlider
       self.slider = QSlider()
       add_widget_with_label(main_layout, self.slider, 'QSlider:')

       # QSpinBox
       self.spin_box = QSpinBox()
       add_widget_with_label(main_layout, self.spin_box, 'QSpinBox:')

       # QProgressBar
       self.progress_bar = QProgressBar()
       add_widget_with_label(main_layout, self.progress_bar, 'QProgressBar:')

       # QTableWidget
       self.table_widget = QTableWidget(5, 3) 
       for i in range(5):
           for j in range(3):
               item = QTableWidgetItem(f"Cell {i+1},{j+1}")
               self.table_widget.setItem(i, j, item)
       add_widget_with_label(main_layout, self.table_widget, 'QTableWidget:')

   def on_button_clicked(self):
       self.label.setText('Button Clicked!')

# Run the application
app = QApplication(sys.argv)
window = DemoWindow()
window.show()
sys.exit(app.exec_())

The output is as follows:

The widgets desktop application (Image by author)

The widgets desktop application (Image by author)

We have successfully created a desktop application that incorporates the most common widgets. For ease of understanding, we have added labels for each of the widgets alongside it. Though this is a sample application, we can now pick and use one of these popular widgets for our more complex applications.

A Data Visualization Application using PySide6, Matplotlib, and Seaborn

To create this application, we shall first pick a popular dataset and create standalone visualizations. This step resembles the day-to-day exploratory data analysis we do in data science work. Then we shall wrap these visualizations into a desktop application, just like how we can transform our reports and analysis to an interactive desktop application.

Before starting, let’s ensure we have all required libraries by running the following command on the terminal.

pip3 install matplotlib seaborn

Step 1: Creating simple standalone visualizations

Here, we load the popular “iris dataset” natively available in the Python visualization package — Seaborn. We use the same package, along with Matplotlib, to create the visualizations. For a comprehensive understanding of plotting with Seaborn, you may want to check out our Python Seaborn visualization guide.

import seaborn as sns
import matplotlib.pyplot as plt
# Load the Iris dataset
iris = sns.load_dataset("iris")

Then, we create visualizations as follows:

plt.figure(figsize=(6, 4))
sns.scatterplot(data=iris, x="sepal_length", y="sepal_width", hue="species")
plt.title("Sepal Length vs Sepal Width")
plt.show()

The first visualization we can see is a scatter plot of sepal length vs. sepal width, colored by species.

Visualization #1: Sepal length vs. sepal width (Image by author)

Visualization #1: Sepal length vs. sepal width (Image by author)

The second visualization is a histogram of petal length, colored by species.

plt.figure(figsize=(6, 4))
sns.histplot(iris, x="petal_length", hue="species", kde=True)
plt.title("Histogram of Petal Length")
plt.show()

And we see the output as:

Visualization #2: Histogram of petal length (Image by author)

Visualization #2: Histogram of petal length (Image by author)

Finally, let’s plot a box plot showing the distribution of petal width across different species.

plt.figure(figsize=(6, 4))
sns.boxplot(x="species", y="petal_width", data=iris)
plt.title("Box Plot of Petal Width")
plt.show()

The visualization is as follows:

Visualization #3: Box plot of petal width (Image by author)

These plots provide different insights into the Iris dataset, showcasing the relationships and distributions of various features across iris species.

Step 2: Integrating visualizations into the desktop application

First, let us see the code, and understand it.

import sys
import seaborn as sns
from PySide6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure

class IrisVisualizer(QMainWindow):
   def __init__(self):
       super().__init__()
       self.setWindowTitle("Iris Dataset Visualizations")
       self.setGeometry(100, 100, 1200, 900)  # x, y, width, height
       self.initUI()

   def initUI(self):
       central_widget = QWidget(self)
       self.setCentralWidget(central_widget)
       layout = QVBoxLayout(central_widget)

       # Adding multiple plots
       self.addScatterPlot(layout)
       self.addHistogram(layout)
       self.addBoxPlot(layout)

   def addPlotCanvas(self, layout, plot_func):
       canvas = FigureCanvas(Figure(figsize=(6, 4)))
       plot_func(canvas.figure)
       layout.addWidget(canvas)

   def addScatterPlot(self, layout):
       def scatter_plot(figure):
           iris = sns.load_dataset("iris")
           ax = figure.add_subplot(111)
           sns.scatterplot(data=iris, x="sepal_length", y="sepal_width", hue="species", ax=ax)
           ax.set_title("Sepal Length vs Sepal Width")

       self.addPlotCanvas(layout, scatter_plot)

   def addHistogram(self, layout):
       def histogram(figure):
           iris = sns.load_dataset("iris")
           ax = figure.add_subplot(111)
           sns.histplot(iris, x="petal_length", hue="species", kde=True, ax=ax)
           ax.set_title("Histogram of Petal Length")

       self.addPlotCanvas(layout, histogram)

   def addBoxPlot(self, layout):
       def box_plot(figure):
           iris = sns.load_dataset("iris")
           ax = figure.add_subplot(111)
           sns.boxplot(x="species", y="petal_width", data=iris, ax=ax)
           ax.set_title("Box Plot of Petal Width")

       self.addPlotCanvas(layout, box_plot)

# Run the application
app = QApplication(sys.argv)
window = IrisVisualizer()
window.show()
sys.exit(app.exec_())

We structure the application around the IrisVisualizer class, which extends PySide6's QMainWindow. This class sets up the main window and its layout, acting as a container for our visualizations. Each plot is embedded into the GUI using FigureCanvasQTAgg from Matplotlib, which allows Matplotlib figures to be displayed as PySide6 widgets.

The key to our integration lies in the addPlotCanvas method. This method creates a Matplotlib figure, renders a plot on it, and then embeds this figure into the application's layout. Specific methods like addScatterPlot, addHistogram, and addBoxPlot define the individual plots, which were our standalone plots earlier. The layout of the main window is set to a vertical box layout (QVBoxLayout), which stacks all the plots vertically.

Let us see our final application:

Iris dataset visualizations desktop application (Image by author)

Iris dataset visualizations desktop application (Image by author)

Isn’t this application better than a plot in the Jupyter Notebook? Of course, this is a simple example, but once we understand the concepts behind creating these applications, we improve them into a fully-fledged data insights dashboard or a data science application.

Conclusion

This tutorial introduced PySide6, a Python library that enables data practitioners to create GUI desktop applications using the most familiar language — Python. We started with installing PySide6 and creating our first desktop application.

We further expanded it to cover the most common widgets used in desktop applications.

Finally, we understood how to incorporate visualizations from popular libraries such as Seaborn and Matplotlib directly into our PySide6 applications.

For further learning, we encourage you to refer to the official documentation and follow your curiosity to create any of your favorite applications. Alternatively, you may also have a look at our tutorial which creates GUI desktop applications in Python but using an alternate library, Tkinter.


Photo of Arunn Thevapalan
Author
Arunn Thevapalan

As a senior data scientist, I design, develop and deploy large-scale machine-learning solutions to help businesses make better data-driven decisions. As a data science writer, I share learnings, career advice, and in-depth, hands-on tutorials.

Topics

Start Your Python Journey Today!

Course

Intermediate Python

4 hr
1.1M
Level up your data science skills by creating visualizations using Matplotlib and manipulating DataFrames with pandas.
See DetailsRight Arrow
Start Course
See MoreRight Arrow
Related

cheat sheet

LaTeX Cheat Sheet

Learn everything you need to know about LaTeX in this convenient cheat sheet!
Richie Cotton's photo

Richie Cotton

tutorial

How to Convert a List to a String in Python

Learn how to convert a list to a string in Python in this quick tutorial.
Adel Nehme's photo

Adel Nehme

tutorial

A Comprehensive Tutorial on Optical Character Recognition (OCR) in Python With Pytesseract

Master the fundamentals of optical character recognition in OCR with PyTesseract and OpenCV.
Bex Tuychiev's photo

Bex Tuychiev

11 min

tutorial

Encapsulation in Python Object-Oriented Programming: A Comprehensive Guide

Learn the fundamentals of implementing encapsulation in Python object-oriented programming.
Bex Tuychiev's photo

Bex Tuychiev

11 min

tutorial

Python KeyError Exceptions and How to Fix Them

Learn key techniques such as exception handling and error prevention to handle the KeyError exception in Python effectively.
Javier Canales Luna's photo

Javier Canales Luna

6 min

code-along

Full Stack Data Engineering with Python

In this session, you'll see a full data workflow using some LIGO gravitational wave data (no physics knowledge required). You'll see how to work with HDF5 files, clean and analyze time series data, and visualize the results.
Blenda Guedes's photo

Blenda Guedes

See MoreSee More