As the demand for web and mobile applications takes over the market, there is a commensurate need for GUI desktop applications. As a developer building GUI applications, you have many tools at your disposal. Some of the most popular include PyQt, Tkinter, PySide2, wxPython, and so on. In this tutorial, we will focus on how to setup PyQt5 to build GUI applications.
PyQt is Python binding for working with the Qt application framework. Qt is one of the most popular toolkits for building desktop GUI applications. One interesting thing about PyQt is that it is cross-platform. This implies that codes developed on one OS can be run on another OS without issues. At least the major OS such as macOS, Windows, Unix, and so on.
In this tutorial, you will learn how to use this library to develop GUI applications with PyQt5. By the end of this tutorial, you will discover:
- Interesting Features about PyQt
- The difference between PyQt4 and PyQt5
- How to Install PyQt5
- Building a Basic GUI Application with PyQt
- Doing More with PyQt5
- Understanding PyQt Components and Widgets
- Some Key PyQt5 Widgets
- How to use the PyQt Designer
Let’s blast off.
Interesting Features about PyQt
Some of the important features of PyQt includes:
- It is cross-platform
- It is used to build power GUI applications
- PyQt has more than 620 classes and 6000 methods and functions
- It can handle XML data
- It has built-in support for managing SQL databases
- PyQt has specialized classes for networking
PyQt4 vs PyQt5
You’d observe PyQt5 has been used since the beginning of this tutorial. This is because there are other previous versions, one of the popular being PyQt4.
Be aware that PyQt5 is cannot be used with PyQt4 (so be mindful of the version you are installing on your machine).
However, you can easily upgrade from PyQt4 to PyQ5. One more thing, note that you cannot use PyQt4 and PyQt5 on your machine at the same time. So what are the major differences?
- PyQt5 can only work with Python 2.6 or later.1. PyQt5 only works with Pyth you on 2.6 or later. In contrast, PyQt4 does support both Python 2 and Python 3.
- Some PyQt5 does not support deprecated features in Qt version 5.0
- Some signals in PyQt4 is not supported, such as QObject.emit(), QObject.connect(), SIGNAL() are not supported in PyQt5
- There are many other compatibility differences and method supports in both versions. Some of such method includes QGraphicsitemAnimation, QMatrix, QFileDialog, QDataStream, QPyObject, QSet, etc
We shall be focusing our attention on the use of PyQt5. Let’s see how to install it on our machine.
How to Install PyQt5
PyQt can easily be installed using pip. If you are using a Python version that is less than Python 3.4, you will manually need to install pip on your system as pip does not come preinstalled.
To install pip, you will first need to download the get-pip.py file. You can download the file here. Make sure you save the file as a py file and take note of the file location. Afterward, open your Command Prompt in the location where the get-pip.py file was saved. Then type the following command.
Once you run the code, the installation begins. After it has been successfully installed, type the following command to install PyQt5
pip install PyQt5
Once you get the ‘successfully installed PyQt5 message’, you can go on to build GUI Applications in Python.
Building a Basic GUI Application with PyQt
Let’s begin by building an empty GUI.
Step 1: We would start by importing the necessary libraries. For this, we will be needing the QtWidgets, QApplication, and QMainWindow class.
#import necessary libraries from PyQt5 import QtWidgets from PyQt5.QtWidgets import QApplication, QMainWindow import sys
Step 2: Instantiate the QApplication
#instantiate the application with which PyQt interfaces with your machine app = QApplication(sys.argv)
These steps allow PyQt to interface with your machine. The argument sys.argv is necessary when you are running the code from a shell. If you attempt to run the code from a shell without the argument, it would throw an error.
Step 3: Create a window and define some specification
create a window for the GUI window = QMainWindow() #set the location for the window window.setGeometry(50, 50, 400, 300) #set the window title window.setWindowTitle('H2k Infosys main page')
The window is the GUI that will be created by instantiating an object from the QMainWindow() class. You may choose to set the location of the window. To do this, make use of the setGeometry() class. This class takes four arguments: the x position, the y position, the width and the height. If you set the x and y position to 0 and 0 respectively, the window will begin at the top left corner of your screen. From that location, the width and height of the window is determined as set.
For the example above, the x and y position was set to 50 pixels. That means the window displays 50 pixels vertically and horizontally from the top left corner of my screen. The width was set to 400 pixels while the height was set to 300 pixels.
You may also decide to give your window a title. For this, you use the setWindowTitle() class. Your preferred title can then be set as an argument in string format. In the sample code above, it was set to ‘H2k infosys main page’.
Step 4: Show the window
#show the window window.show()
After creating the window, the window would not be displayed until you explicitly hardcode your program to show it, using the show() method.
Step 5: Close the window
#exit the application sys.exit(app.exec_())
Finally, to make sure that the GUI application closes when you click the ‘X’ button, you have to type in the following code.
Now, we have explained all the steps. Let’s pull it all together and run it as a single code. The entire process was defined in a function to make the code cleaner. The code is shown below.
#import necessary libraries from PyQt5 import QtWidgets from PyQt5.QtWidgets import QApplication, QMainWindow import sys #create function to build GUI def create_window(): #instantiate the application with which PyQt interfaces with your machine app = QApplication(sys.argv) #create a window for the GUI window = QMainWindow() #set the location for the window window.setGeometry(50, 50, 400, 300) #set the window title window.setWindowTitle('H2k Infosys main page') #show the window window.show() #exit the application sys.exit(app.exec_()) #call the function create_window()
As seen, the empty GUI application was shown. Now, let’s build some more fun stuff.
Doing More with PyQt5
In this section, we will add more functionality to our code. Let’s say we wish to add a button that when clicked upon creates another window that would prompt the user to reveal a message. To do this, use the code shown below.
#import necessary libraries from PyQt5 import QtWidgets from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QMessageBox import sys #create function to build GUI def create_window(): def dialog(): message_dialog = QMessageBox() message_dialog.setText("Click on 'Show Details' for surprise") message_dialog.setDetailedText("You are amazing!") message_dialog.setStandardButtons(QMessageBox.Cancel) message_dialog.setWindowTitle('H2k Infosys Surprise') message_dialog.exec_() if __name__ == '__main__': #instantiate the application with which PyQt interfaces with your machine app = QApplication(sys.argv) #create a window for the GUI window = QMainWindow() #set the location for the window window.setGeometry(0, 0, 400, 400) #set the window title window.setWindowTitle('H2k Infosys main page') #create button button = QPushButton(window) button.setText('Click here') button.move(150,150) button.show() button.clicked.connect(dialog) # add a label on the window label = QtWidgets.QLabel(window) label.setText('Welcome') #show the window window.show() #exit the application sys.exit(app.exec_()) create_window()
When you run the code, the window above shows.
If you click on ‘Click Here’, the second window shows.
As seen, the code runs as expected. Let’s unpack the code above.
We begin by importing all necessary libraries.
#import necessary libraries from PyQt5 import QtWidgets from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QMessageBox import sys
Notice that this time, two new classes were imported, the QPushButton (for creating a clickable button) and the QMessageBox for creating a window that displays a message.
Next, we create a function that would create a message dialog when the Click here button is created. Note that this function will be called when creating the main window so it needs to be created first.
def dialog(): """This function creates a dialog box""" #instantiate the message dialog box message_dialog = QMessageBox() #define the text you wish to display message_dialog.setText("Click on 'Show Details' for surprise") #define the hidden text in the Show More button message_dialog.setDetailedText("You are amazing!") #add the cancel button message_dialog.setStandardButtons(QMessageBox.Cancel) #set the message dialog box title message_dialog.setWindowTitle('H2k Infosys Surprise') #execute the program message_dialog.exec_()
Next, we create the main window. More like what we did in the first example. The only difference is that this time, we create a button and add a label. To create a button, use the QPushButton() class. Remember that the created window object must be passed as an argument for the button. This tells the Python Interpreter, the window where the button will be created.
We can also decide to add a label to the window. T a and to create a label, use the QLabel() class.
if __name__ == '__main__': #instantiate the application with which PyQt interfaces with your machine app = QApplication(sys.argv) #create a window for the GUI window = QMainWindow() #set the location for the window window.setGeometry(0, 0, 400, 400) #set the window title window.setWindowTitle('H2k Infosys main page') #create button button = QPushButton(window) button.setText('Click here') button.move(150,150) button.show() button.clicked.connect(dialog) # add a label on the window label = QtWidgets.QLabel(window) label.setText('Welcome') #show the window window.show() #exit the application sys.exit(app.exec_())
You may be wondering if you created the window if __name__ = ‘__main__’. This is a check to make sure if someone else imports this code as a module in their program. The new program would make use of the functions defined but would not be executed automatically. The function only gets executed when the programmers call the function in the new code.
Let’s say a function was created in a class to print ‘Hello world’, the class is imported to a new code, ‘Hello world’ would not be printed until the programmer called the function explicitly.
Also notice the button object had methods such as setText(), move(), show() and clicked.connect(). These are used to set the properties and functionalities of the button.
- The setText() determines the text that will be printed on the button. Here it was set to ‘Click here’.
- The move() method defines the position of the button. It takes two arguments, the width, and height. In the code above, they were both set to 150 pixels.
- The show() method is used to show the dialog box
- The clicked.connect() method is used to set what happens when the button is clicked. Notice that the function ‘dialog’ was passed. It means that once a user clicks the button, the python interpreter will execute the dialog function. In our case, it was a message box with some secret message.
Let’s discuss two concepts here: events and slots.
When building GUI applications in PyQt and you connect a button to a function, the function gets executed based on the user’s action. Such actions are called events. So the clicking of a button or hovering the mouse over an element are examples of action. The app.exec_() is used to transfer the control of events to the PyQt event loop.
But some action is meant to take place after an event. Clicking a button should return something different. In python, when an event takes place, the connected widget function sends some signal. It is the connected function that determines the next action after an event. Such functions are called slots.
In the coding example, when the user clicks the ‘Click here’ button, a signal is sent to the MessageDialog function (called a slot). The MessageDialog function gets called automatically, which then displays the second dialog box.
In summary, slots and events are used to allow PyQt interface between user actions and functions in the code. Such that a function reused at different points in the code.
Understanding PyQt Components and Widgets
The Widgets in PyQt5 are numerous. They are seen as the crux of PyQt and we would come to some of the important widgets in a bit. First, let’s take some time to understand the components of PyQt. When PyQt5 was released, there were a couple of changes in the modules. To have a robust understanding of how to navigate PyQt, it is fundamental to understand how the various modules, libraries, classes, etc are organized.
Speaking of the modules, these are the key modules in PyQt5.
- Qt: This is the library that combines the other functions/modules. Qt will generally consume more memory and space since it can be used for general purposes. It is however great since it allows you to manage all the frameworks by importing only a library.
- QtWidgets: This is perhaps one of the most used libraries. It holds most of the widgets you will find in PyQt5
- QtCore: QtCore is dedicated to classes used by other modules that are non-graphical. They include signals, slot-connectivity, event loops, etc.
- QtNetwork: This library contains all the classes and functions that would be required to carry out network programming through the Qt platform. It supports key networking operations such as DNS searches, SSL handling, TCP servers, UDP sockets, network sessions, and so on.
- QtGui: This is seen as an extension of the QtCore module. But QtGui deals with the graphical user interface components and operations.
- QtSql: This allows for SQL database integration and implementation. It supports the most popular commercial databases such as PostgreSQL, SQLite, MySQL, ODBC, Oracle, etc.
- QtMultimedia: This library is used for multimedia functionality. However, this library is limited to low-level operations.
Now let’s talk about some important PyQt5 Widgets
Some Key PyQt5 Widgets
- QLineEdit: This widget is used to allow a line of text to be imputed by the user.
- QRadioButton: This is used to create an input field that has a button for selection.
- QComboBox: This is used to create a dropdown to a list of items that can be selected. After instantiating the QComboBox object, you need to use the addItems() method to add the list of items you want in the drop-down
- QCheckBox: This is used to checkbox that can be placed in front of a label.
- QScrollBar: This is used to create a bar where the user can scroll up or down within the window
- QMenuBar: This is used to create a menu bar where other selected items can be placed.
- QTab: This is used to create multiple tabs or pages in the window.
How to use the PyQt Designer
PyQt Designer is a software that is used to create GUI applications with a simple drag and drop interface. To make use of this application, you need to first install PyQt5 tools. Head over to your command prompt and type the following command
pip install pyqt5-tools
Once it has successfully been installed, head over to the file path of the installation. On my machine, it was c:\users\dell\appdata\local\programs\python\python 38-32\lib\site-packages (from pyqt5-tools).
If you can’t find the AppData file on your PC, on the menu bar of your Windows Explorer, navigate to the view tab. Check the ‘Hidden items’ box.
Now find the Qt Designer application. From your lib folder, you can follow this directory. \Lib\site-packages\qt5_applications\Qt\bin
In the bin folder, you will find the Designer application. Open it
Click on Main Window and you can begin to drag and drop widgets from the left side pane.
After playing around with the widgets to create your GUI application. You can export the code. Let me show you how.
Let’s say I created this simple GUI application and I want to get the Python code.
Save the file as a .ui file in whichever file path you like.
Now navigate to the file path and open a command line in the path. Once the command prompt opens, type the code below
pyuic5 -x gui.ui -o gui.py
My file was saved as gui. You can change the file name to whatever name you wish. Once that runs, a .py file is added to the file path. Open the py file with any code editor to access the code of the GUI you created.
The file contains the python code.
# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'gui.ui' # # Created by: PyQt5 UI code generator 5.15.2 # # WARNING: Any manual changes made to this file will be lost when pyuic5 is # run again. Do not edit this file unless you know what you are doing. from PyQt5 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(668, 569) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.pushButton = QtWidgets.QPushButton(self.centralwidget) self.pushButton.setGeometry(QtCore.QRect(180, 380, 281, 41)) font = QtGui.QFont() font.setPointSize(14) self.pushButton.setFont(font) self.pushButton.setObjectName("pushButton") self.box1 = QtWidgets.QCheckBox(self.centralwidget) self.box1.setGeometry(QtCore.QRect(130, 160, 70, 17)) self.box1.setObjectName("box1") self.label = QtWidgets.QLabel(self.centralwidget) self.label.setGeometry(QtCore.QRect(240, 40, 211, 81)) font = QtGui.QFont() font.setFamily("Georgia") font.setPointSize(28) font.setBold(True) font.setWeight(75) self.label.setFont(font) self.label.setObjectName("label") self.label_2 = QtWidgets.QLabel(self.centralwidget) self.label_2.setGeometry(QtCore.QRect(80, 120, 241, 41)) font = QtGui.QFont() font.setPointSize(12) font.setBold(True) font.setWeight(75) self.label_2.setFont(font) self.label_2.setObjectName("label_2") self.box2 = QtWidgets.QCheckBox(self.centralwidget) self.box2.setGeometry(QtCore.QRect(130, 190, 70, 17)) self.box2.setObjectName("box2") self.box3 = QtWidgets.QCheckBox(self.centralwidget) self.box3.setGeometry(QtCore.QRect(130, 220, 70, 17)) self.box3.setObjectName("box3") self.box4 = QtWidgets.QCheckBox(self.centralwidget) self.box4.setGeometry(QtCore.QRect(130, 250, 121, 17)) self.box4.setObjectName("box4") self.box5 = QtWidgets.QCheckBox(self.centralwidget) self.box5.setGeometry(QtCore.QRect(130, 280, 141, 17)) self.box5.setObjectName("box5") MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 668, 21)) self.menubar.setObjectName("menubar") self.menufirstWindow = QtWidgets.QMenu(self.menubar) self.menufirstWindow.setObjectName("menufirstWindow") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.menubar.addAction(self.menufirstWindow.menuAction()) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.pushButton.setText(_translate("MainWindow", "Click here when you are done")) self.box1.setText(_translate("MainWindow", "Python")) self.label.setText(_translate("MainWindow", "Welcome")) self.label_2.setText(_translate("MainWindow", "What do you wish to learn?")) self.box2.setText(_translate("MainWindow", "Java")) self.box3.setText(_translate("MainWindow", "Selenium")) self.box4.setText(_translate("MainWindow", "Business Intelligence")) self.box5.setText(_translate("MainWindow", "Quality Assurance")) self.menufirstWindow.setTitle(_translate("MainWindow", "firstWindow")) if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) MainWindow = QtWidgets.QMainWindow() ui = Ui_MainWindow() ui.setupUi(MainWindow) MainWindow.show() sys.exit(app.exec_())
In this tutorial, you have discovered how to create GUI applications using PyQt5. You have learned how to create an empty window and filled it with a widget for some functionalities. Some of the popular Widgets include buttons, text labels, text fields, check boxes, push buttons etc.
If you have any questions, feel free to leave them in the comment section and I’d do my best to answer them.