Creating Custom Widgets in PyQt5

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

filter_none

edit
close

play_arrow

link
brightness_4
code

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_())

chevron_right


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:

filter_none

edit
close

play_arrow

link
brightness_4
code

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())

chevron_right


which outputs to

Widget Skeleton

An empty widget looks like this:

filter_none

edit
close

play_arrow

link
brightness_4
code

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

chevron_right


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

filter_none

edit
close

play_arrow

link
brightness_4
code

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())

chevron_right


Using Like A Normal Widget



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

filter_none

edit
close

play_arrow

link
brightness_4
code

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

chevron_right


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

filter_none

edit
close

play_arrow

link
brightness_4
code

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_())

chevron_right


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

Attention geek! Strengthen your foundations with the Python Programming Foundation Course and learn the basics.

To begin with, your interview preparations Enhance your Data Structures concepts with the Python DS Course.




My Personal Notes arrow_drop_up


If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.


Article Tags :

Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.