Integrating a Python-based Custom Widget into Qt Designer

Jeff Tranter


Jeff Tranter is a Qt Consulting Manager at ICS. Jeff oversees the architectural and high-level design of software systems for clients. Jeff’s leadership organizes global teams of developers on desktop and embedded applications.

By Jeff Tranter | Wednesday, February 1, 2017

In an earlier blog post (1) I described how to create a widget with a Qt Designer plugin interface so it can be viewed within Qt Designer. With the increased interest in using Qt from the Python programming language, I asked one of our developers to reproduce the same example, but implement the widget in Python with PyQt. 

Not all the steps to do this are obvious so I'll walk you through.

Example Files

The download link (2) contains the example code referenced in this blog post. It includes the following source files:

ledwidget.py: A port of the earlier LED widget to Python and PyQt. It is similar to the code in the C++ version.

ledplugin.py: This implements a Designer plugin by subclassing the QPyDesignerCustomWidgetPlugin class and providing the required methods for a plugin.

ledGallery.ui: This is a Qt Designer UI file that has several LED widgets and some controls to adjust the state, flashing, and flash rate. Nothing here is specific to Python.

The key to using a PyQt widget from Qt Designer is a Qt Designer plugin to support PyQt widgets. That is not part of standard Qt itself, but rather part of PyQt, specifically a shared library libpyqt5.so. We will need to build this plugin as one of the steps to run the example code.

Steps

I'll go over the steps needed to make this example work on a Linux desktop system. I used a recent version of Ubuntu Linux, but the steps should be the same on other distributions.

Since most Linux distributions include Qt and PyQt, you may be able to run the example code using the software packages provided by your Linux distribution rather than building it yourself. In my case (Ubuntu 14.04.5) it did not work for me. I didn't spend further time on it as I generally build Qt myself from source so that I can use a more recent Qt release than that provided by the Linux distribution.

Instead, we'll build the necessary code from source so that it can work with a version of Qt you may have compiled yourself. I will assume you already have installed Python 3 and some version of Qt 5. You will want to have the Python development tools installed. On Ubuntu these are in the package libpython3.4-dev, which you can install by running

% sudo apt-get install libpython3.4-dev

(It may be libpython3.5-dev if you are using a newer Ubuntu release.)

Installing SIP

We will install PyQt so that we can use Qt from Python. This includes the Qt Designer plugin to support PyQt widgets.

In order to build PyQt we need the SIP software. SIP is a tool that makes it easy to create Python bindings for C and C++ libraries. The latest PyQt release needs SIP version 4.19 or later, but my Ubuntu system only provides SIP 4.15 so we need to download and build this newer version of SIP.

Go to https://www.riverbankcomputing.com/software/sip/download and download it. Extract the code from the download archive, configure it, build it, and then install it. These were the commands I used to do this:

% wget https://sourceforge.net/projects/pyqt/files/sip/sip-4.19/sip-4.19.tar.gz
% tar xzvf sip-4.19.tar.gz
% cd sip-4.19
% python3 configure.py
% make
% sudo make install
% cd ..

This should not take very long. You can verify that the new version is in your search path and runs:

% sip -V
4.19

Installing PyQt

Now we need to build PyQt. It gets built against a specific Qt install, so download the version of PyQt that matches your Qt version from https://sourceforge.net/projects/pyqt/files/PyQt5/. In my case it was Qt 5.7.1. I downloaded and built it using these commands:

% wget https://sourceforge.net/projects/pyqt/files/PyQt5/PyQt-5.7.1/PyQt5_gpl-5.7.1.tar.gz
% tar xzvf PyQt5_gpl-5.7.1.tar.gz
% cd PyQt5_gpl-5.7.1
% python3 configure.py
% make
% sudo make install

This will take some time as PyQt is quite large, and it has to create Python bindings for all of the classes and methods in Qt's libraries.

Running The Example

We can now launch Designer to view our UI file that uses the Python-based LED widget. In order for Designer's Python plugin to find the widget, we need to point it to the location using an environment variable, PYQTDESIGNERPATH. If the files are in the current directory we can run it as follows:

% PYQTDESIGNERPATH=. designer ledGallery.ui 

In the screen shot below you can see the Qt Designer form showing some LED widgets.

If we select Form / Preview... we can preview the form and the UI controls can toggle the LED state, flashing mode, and flash rate in the preview window:

Summary

Most of the effort to get this demonstration working involves building SIP and PyQt. Once you've done that, you can use Qt Designer to preview any widgets that you develop in Python with PyQt and see how they will appear in your application.

(Thanks go to my ICS colleague Kirill Bukaev for developing this demonstration code.)

References

1. Integrating a Custom Widget into Qt Designer, ICS blog post, http://www.ics.com/blog/integrating-custom-widget-qt-designer
2. Link to downloadable example code, ftp://ftp.ics.com/pub/pickup/python-designer-plugin.zip
3. PyQt download link, PyQt SourceForge Project, https://sourceforge.net/projects/pyqt/files/PyQt5/
4. SIP download link, Riverbank Computing website, https://www.riverbankcomputing.com/software/sip/download



Have a question or add to the conversation: Log in Register