Open In App

Creating Custom Widgets in PyQt5

Last Updated : 11 May, 2020
Improve
Improve
Like Article
Like
Save
Share
Report

PyQt5 is one of the most advanced GUI library for Python. While being powerful, it’s also well structured and makes it easy for you to build ‘advanced’ items. Custom widgets in PyQt5 is a breeze.

The below has a well-described way of building custom Widgets with PyQt5,

The Main Window
Let’s start by creating our main window. We go the OOP route right from the start. An OOP-less way is a pain for maintenance. Our skeleton looks like this




import sys
  
from PyQt5 import QtWidgets
from PyQt5 import QtCore
from PyQt5 import QtGui
  
  
class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent = None):
        super().__init__(parent)
        self.init_gui()
  
    def init_gui(self):
        self.window = QtWidgets.QWidget()
        self.layout = QtWidgets.QGridLayout()
        self.setCentralWidget(self.window)
        self.window.setLayout(self.layout)
  
          
  
  
if __name__ == '__main__':
    app = QtWidgets.QApplication([])
  
    win = MainWindow()
    win.show()
  
    sys.exit(app.exec_())


which outputs to

A Normal App

Let’s add a textbox and a label that just echoes whatever we type.
Our main window turns to this:




class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent = None):
        super().__init__(parent)
        self.init_gui()
  
    def init_gui(self):
        self.window = QtWidgets.QWidget()
        self.layout = QtWidgets.QGridLayout()
        self.setCentralWidget(self.window)
        self.window.setLayout(self.layout)
  
        self.textbox = QtWidgets.QLineEdit()
        self.echo_label = QtWidgets.QLabel('')
  
        self.textbox.textChanged.connect(self.textbox_text_changed)
  
        self.layout.addWidget(self.textbox, 0, 0)
        self.layout.addWidget(self.echo_label, 1, 0)
  
    def textbox_text_changed(self):
        self.echo_label.setText(self.textbox.text())


which outputs to

Widget Skeleton

An empty widget looks like this:




class MyWidget(QtWidgets.QWidget):
  
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.layout = QtWidgets.QGridLayout()
        self.setLayout(self.layout)


Let’s name it as EchoText and add what we added to our main window




class EchoText(QtWidgets.QWidget):
  
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.layout = QtWidgets.QGridLayout()
        self.setLayout(self.layout)
  
        self.textbox = QtWidgets.QLineEdit()
        self.echo_label = QtWidgets.QLabel('')
  
        self.textbox.textChanged.connect(self.textbox_text_changed)
  
        self.layout.addWidget(self.textbox, 0, 0)
        self.layout.addWidget(self.echo_label, 1, 0)
  
    def textbox_text_changed(self):
        self.echo_label.setText(self.textbox.text())


Using Like A Normal Widget

In our main window, leave only the skeleton and add the following:




self.echotext_widget = EchoText()
  
self.layout.addWidget(self.echotext_widget)


and it gets displayed as when we coded everything in the main window itself.

The Complete App

Here’s the complete code for the entire application




import sys
  
from PyQt5 import QtWidgets
from PyQt5 import QtCore
from PyQt5 import QtGui
  
class EchoText(QtWidgets.QWidget):
  
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.layout = QtWidgets.QGridLayout()
        self.setLayout(self.layout)
  
        self.textbox = QtWidgets.QLineEdit()
        self.echo_label = QtWidgets.QLabel('')
  
        self.textbox.textChanged.connect(self.textbox_text_changed)
  
        self.layout.addWidget(self.textbox, 0, 0)
        self.layout.addWidget(self.echo_label, 1, 0)
  
    def textbox_text_changed(self):
        self.echo_label.setText(self.textbox.text())
  
  
class MainWindow(QtWidgets.QMainWindow):
  
    def __init__(self, parent = None):
        super().__init__(parent)
        self.init_gui()
  
    def init_gui(self):
        self.window = QtWidgets.QWidget()
        self.layout = QtWidgets.QGridLayout()
        self.setCentralWidget(self.window)
        self.window.setLayout(self.layout)
  
        self.echotext_widget = EchoText()
  
        self.layout.addWidget(self.echotext_widget)
  
if __name__ == '__main__':
    app = QtWidgets.QApplication([])
  
    win = MainWindow()
    win.show()
  
    sys.exit(app.exec_())


Try creating a different widget and adding it. PyQt5 sounds tougher than Tkinter to get started but it’s worth it!



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads