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.
Updated 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!

Certification available

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

Becoming Remarkable with Guy Kawasaki, Author and Chief Evangelist at Canva

Richie and Guy explore the concept of being remarkable, growth, grit and grace, the importance of experiential learning, imposter syndrome, finding your passion, how to network and find remarkable people, measuring success through benevolent impact and much more. 
Richie Cotton's photo

Richie Cotton

55 min

Python NaN: 4 Ways to Check for Missing Values in Python

Explore 4 ways to detect NaN values in Python, using NumPy and Pandas. Learn key differences between NaN and None to clean and analyze data efficiently.
Adel Nehme's photo

Adel Nehme

5 min

Seaborn Heatmaps: A Guide to Data Visualization

Learn how to create eye-catching Seaborn heatmaps
Joleen Bothma's photo

Joleen Bothma

9 min

Test-Driven Development in Python: A Beginner's Guide

Dive into test-driven development (TDD) with our comprehensive Python tutorial. Learn how to write robust tests before coding with practical examples.
Amina Edmunds's photo

Amina Edmunds

7 min

Exponents in Python: A Comprehensive Guide for Beginners

Master exponents in Python using various methods, from built-in functions to powerful libraries like NumPy, and leverage them in real-world scenarios to gain a deeper understanding.
Satyam Tripathi's photo

Satyam Tripathi

9 min

Python Linked Lists: Tutorial With Examples

Learn everything you need to know about linked lists: when to use them, their types, and implementation in Python.
Natassha Selvaraj's photo

Natassha Selvaraj

9 min

See MoreSee More