Qt Designer is a great tool for designing PySide6 GUIs, allowing you to use the entire range of Qt widgets and layouts to construct your apps. As your applications get more complex, however, you may find yourself creating custom widgets or using PySide6 libraries such as PyQtGraph, whose widgets are not available within Designer.
Helpfully, Qt Designer supports a mechanism for using placeholder widgets to represent your custom or external widgets in your design. This tutorial will walk you through the process of using placeholders to include a PyQtGraph plot in your app from within Qt Designer.
Promoting Widgets
The principle of using placeholders in Qt Designer is quite straightforward:
- Create a UI as usual in Qt Designer.
- Add a placeholder widget to represent the custom widget you're adding.
- Tell Qt to replace your placeholder with your actual widget when building the UI.
In Qt, this final step is referred to as promoting (as in promoting a base class).
If the custom widget you are adding is a subclass of an existing Qt widget, you may want to use the base class as your placeholder to promote from. For example, if you have a custom MyAwesomeButton
button widget subclassed from QPushButton
, use QPushButton
as the placeholder and promote it to MyAwesomeButton
. This gives you access to the base class properties, events, and actions from within Qt Designer.
If you don't have an obvious base class to use, then you can use QWidget
, the common base class of all Qt widgets.
PyQtGraph
Data science is one of the most popular use cases of Python, and building dashboards and analysis tools is a common use case of PySide. For all of these, being able to add plots to your UI is very useful — and being able to do this from Qt Designer is even more so.
Purchasing Power Parity
Developers in [[ country ]] get [[ discount.discount_pc ]]% OFF on all books & courses with code [[ discount.coupon_code ]]There are a number of plotting libraries available in Python, with matplotlib being the most popular and offering some basic support for PySide. PyQtGraph is a popular alternative that uses Qt's native QGraphicsScene
to provide fast zooming, scaling, and drag-drop behavior that feels like a natural part of your application.
Whether you're using PyQtGraph or maplotlib for your plotting needs, the plot canvas widgets are not available from within Qt Designer. In this tutorial, we'll go through the process of using these custom widgets in your apps.
If you don't have PyQtGraph installed already, you can install it using the following command:
$ python -m pip install pyqtgraph
The instructions below aren't specific to PyQtGraph, and you can use a similar command to add Matplotlib or any other custom widgets to your app.
Qt Designer
We will be using Qt Designer to create a simple UI design and add a placeholder for our PyQtGraph widget. First, open Qt Designer and create a new QMainWindow
as usual.
Qt Creator — Select MainWindow for widget type
We next need to add the placeholder widget. As there is no suitable baseclass for the PyQtGraph plot widget, we'll use the basic QWidget
as our placeholder. Select the Widget from the left sidebar and place it in the center of your window.
Give the widget a name, graphWidget
will do. This is just a tag to reference the element in your code.
Add a widget to the window. Name the widget as "graphWidget"
Right-click the widget and select the Promote to option from the widget's context menu.
Promoting a QWidget
indicates that it should be replaced with the specified subclass, in our case, the PyQtGraph plot widget.
A promoted widget can be reverted back to its base class by right-clicking and choosing Demote to from the widget's context menu.
Right click to show the promotion menu
You will be presented with a dialog to specify the custom widget class the placeholder widget will become.
The header file is the name of the Python module used to import the class, which is pyqtgraph
. Specify PlotWidget
as the class name of the widget to replace it with.
Promote the widget by specifying the class name as PlotWidget and the header file as pyqtgraph.
The name you use for the file doesn't matter, but it's usually a good idea to name it after the class you're going to create with it.
Voila! The widget is now promoted to a canvas to plot. But you won't be able to see any changes within Qt Designer. Save the window as mainwindow.ui
in the same directory as your PySide app.
For a complete guide to using Qt Designer's .ui
files in Python, check out First steps with Qt Creator.
Loading the .ui
File
We now have the mainwindow.ui
file containing our UI definition. We can load this from Python to show the window and our custom widget.
Let's start from a basic app template.
import sys
from PySide6.QtWidgets import QApplication
import pyqtgraph as pg
uiclass, baseclass = pg.Qt.loadUiType("mainwindow.ui")
class MainWindow(uiclass, baseclass):
def __init__(self):
super().__init__()
self.setupUi(self)
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
In this example, we're using PyQtGraph's helper method pg.Qt.loadUiType
to load the UI. This gives us access to the designed UI class and the base class (in this case QMainWindow
). With these, we can create our own custom QMainWindow
subclass to add our plotting methods to.
PyQtGraph supports PyQt and PySide. We can manually define which library to use by importing it before importing pyqtgraph
. In this tutorial, we're forcing PyQtGraph to use PySide6. Note that if you use some import-sorting tools like isort, then the code above may not work correctly because those tools swap the import order, which means that PyQtGraph will be imported before PySide6.
Save the code above in the same folder as your mainwindow.ui
file, and run it as normal:
$ python my_app.py
Your graph is now embedded
You'll see a window with your widget transformed into a PyQtGraph plotting widget.
Let's now create a method to make a plot of hours vs temperature data:
import sys
from PySide6.QtWidgets import QApplication
import pyqtgraph as pg
uiclass, baseclass = pg.Qt.loadUiType("mainwindow.ui")
class MainWindow(uiclass, baseclass):
def __init__(self):
super().__init__()
self.setupUi(self)
self.plot(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], # Hours
[30, 32, 34, 32, 33, 31, 29, 32, 35, 45], # Temperature
)
def plot(self, hour, temperature):
self.graphWidget.plot(hour, temperature)
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
So we added the plot()
method, which accepts two arrays, hour
and temperature
. Then it plots the data using the .plot()
method on graphWidget
.
Run the code, you should see the following.
The custom PyQtGraph widget showing dummy data.
That's it! You have just embedded your first plot with PyQtGraph.
The default PyQtGraph plot doesn't look quite polished. You can play around with the .plot()
call to change the data and see how the plot changes.
In upcoming tutorials, we'll learn how to create more elaborated PyQtGraph plots and how to customize your plots, including line colors, styles, and alternative types of plots.
Packaging Python Applications with PyInstaller by Martin Fitzpatrick — This step-by-step guide walks you through packaging your own Python applications from simple examples to complete installers and signed executables.