Python Graphical User Interface
When it comes to crafting dynamic and organized user interfaces in PyQt5, widgets are your ultimate toolkit. The List Widget allows for seamless presentation and interaction with lists of items, making it essential for everything from to-do lists to file explorers. The Tree Widget elevates your app’s functionality, offering hierarchical data visualization that is perfect for displaying parent child relationships, like file directories or organizational charts and for those seeking structure and precision, the Table Widget is indispensable for managing and displaying tabular data, offering flexibility and control over multi-column layouts. Each of these widgets brings unique power to your application, transforming basic interfaces into robust, interactive environments that enhance user experience.
Table of Content
- Introduction
- List widget
- Tree widget
- Table widget
Introduction
In the previous sections, we discussed different item views in
PyQt5. In this section, we will focus on Item Widgets. Our
primary focus in this section will be on learning about List
Widget, Tree Widget and Table Widget. We will be focusing on
properties and some useful methods. All these widgets are
available under Item Widgets in Qt Designer, as shown in the figure 1.1, where the user can select any of the
widgets under Item Widgets and drag and drop in a GUI form.
We have already seen about QObject and QWidget classes when
we were dealing with button type widgets. The same applies
to Item Widgets too. We have already discussed other classes
about QFrame, QAbstractScrollArea and QAbstractItemView class in
the previous section. The Item Widgets have all these range of
properties. But the default values may differ from widget to
widget. Now, we shall be discussing 3 item widgets and their
properties.
List Widget
List widget is a classic item based interface for adding and
removing items. It has a list view similar to the one supplied
by QListView, provided by the convenience class QListWidget. An
item based interface to add or delete items from a list is the
QListWidget class. The list’s items are all QListWidgetItem objects.
Each QListWidgetItem in the list is managed by QListWidget using
an internal model. The multi selectability feature can be set
for the QListWidget object.
Important Properties
We have already seen the different QListView properties in the
previous chapter. The same properties apply here too. Apart
from these properties, we shall discuss QListWidget properties.
Current row
The current item’s row is set using this property. The row
may also be selected depending on the active selection
mode. Default value is -1.
Designer
Sorting enabled
The default value is unchecked and when set to true, this
property will decide that sorting is enabled for the list.
Designer
Important Methods
- clear(): All the items from the QListWidget object will be
removed as it will be permanently deleted. - insertItem(row, item): The QListWidgetItem object will be
inserted at the position specified by the row (integer). - addItem(): Either a QListWidgetItem object or string will be
added to the QListWidget object. - addItems(labels): Items with a list of strings will be
inserted at the end of the QListWidget object. - setCurrentItem(item, command): Programmatically, we can
set the currently selected item to the QListWidgetItem
object with/without the usage of selection flags, that is,
using the command parameter. - sortItems([order=Qt.AscendingOrder]): QListWidget items will
be arranged according to the specified order.
Important Signals
- currentItemChanged(): The signal is emitted whenever the
current item changes of the QListWidget object. - itemClicked(): The signal is emitted whenever an item in
the QListWidget object is clicked.
Now, we shall see an example of QListWidget.
Consider the following code of run_listWidget_eg1.py:
import sys
from PyQt5.QtWidgets import
QMainWindow,QAbstractItemView,
QApplication,QListWidgetItem,QCheckBox,QHBoxLayout,
QLabel,QWidget, QMessageBox
from PyQt5.QtGui import QPalette, QColor
from listWidget_eg1 import *
class MyListWidget(QMainWindow):
def __init__(self):
super().__init__()
self.myui = Ui_MainWindow()
self.myui.setupUi(self)
self.myui.lw_Add.clicked.connect(self.btn1)
self.myui.lw_Count.clicked.connect(self.btn2)
self.myui.lw_Clear.clicked.connect(self.btn3)
self.myui.lw_SortAsc.clicked.connect(self.btn4)
self.myui.lw_Toggle.clicked.connect(self.btn5)
self.myui.lw_SetCurrentItem.clicked.connect(self.btn6)
self.myui.lw_AddCheckBox.clicked.connect(self.btn7)
self.myui.lw1.setDragEnabled(True) #
allowing dragenabled property of lw1 to be True
self.myui.lw2.setDragEnabled(False)#
allowing dragenabled property of lw2 to be False
self.myui.lw1.setDragDropMode(QAbstractItemView.DragDrop) # setting dag drop mode of lw1
self.myui.lw1.setAcceptDrops(False)#
allowing acceptDrops property of lw1 to be False
self.myui.lw2.setAcceptDrops(True)#
allowing acceptDrops property of lw2 to be True
self.show()
# Add items to the list widget
for loop in range(5):
item = QListWidgetItem()
item.setText(" Itemmno:
{}".format(loop+1))
self.myui.lw1.addItem(item)
def btn1(self):
# creating an instance of QListWidgetItem
item = QListWidgetItem()
# setting the text
item.setText(" Itemmno:
{}".format(self.myui.lw1.count()+1))
# adding it to the listWidget using addItem
method
self.myui.lw1.addItem(item)
# Add multiple items to the list widget
mylist_items = [" Zeeshan", " Vicky",
" Abdul"]
for list_item in mylist_items:
myinst_item = QListWidgetItem()
myinst_item.setText(list_item)
self.myui.lw1.addItem(myinst_item)
def btn2(self):
QMessageBox.information(None, 'Item Count
Title', "The number of items in the list is
{}".format(self.myui.lw1.count()))
def btn3(self):
# clearing all the listWidget items
self.myui.lw1.clear()
def btn4(self):
# Sorting the listWidget items in ascending order
self.myui.lw1.sortItems(QtCore.Qt.AscendingOrder)
def btn5(self):
# Enable alternate row colors
self.myui.lw1.setAlternatingRowColors(True)
mypalette = self.myui.lw1.palette()
mypalette.setColor(QPalette.AlternateBase,
QColor("lightgray"))
self.myui.lw1.setPalette(mypalette)
def btn6(self):
myselect_item = self.myui.lw1.item(4) #
Selecting 5th item of the list
self.myui.lw1.setCurrentItem(myselect_item)
# will set the current item of the listWidget
# Emitting the itemSelectionChanged signal
self.myui.lw1.itemSelectionChanged.emit() #
signal will be emitted when the selection of items
in the list widget is changed
def btn7(self):
#Create a checkbox for each ListWidget item
for myitm in range(self.myui.lw1.count()):
myitem = self.myui.lw1.item(myitm)
mycheck_box = QCheckBox()
self.myui.lw1.setItemWidget(myitem, mycheck_box)
if __name__=="__main__":
app = QApplication(sys.argv)
w = MyListWidget()
w.show()
sys.exit(app.exec_())
Case 2 — On pressing Count button
Case 3 — On pressing Sort Ascending Order button
Case 4 — On pressing Toggle Alternating RowColors button
Case 5 — On pressing the Set Current item and Emit Item Selection Changed Signal button
Case 6 — On pressing the Adding checkbox to each Item of List Widget1 button
Case 7 — On pressing Clear button
Case 8 — Drag and Drop from lw1 to lw2 only
Tree Widget
The PyQt5 library’s QTreeWidget class offers a treeView widget
for displaying data in a hierarchical structure. It supports
multiple columns and custom items and the user can
expand and collapse branches to view and edit items. Data
can be displayed using it, including a file system, database or list of items with parent-child relationships. The QTreeWidget
class utilizes a default model to hold items, each of which is
a QTreeWidgetItem, and is based on Qt’s Model/View
architecture.
Important Properties
The properties of QTreeWidget are similar to the QTreeView
properties seen in the previous section. Apart from these
properties, the only other property which is added is
columnCount property. This property will return the number of
columns count in the QTreeWidget. Default value is set to 1. We
can also set the column count by using the
setColumnCount(count) method.
Designer
- clear(): All the items from the QTreeWidget object will be
removed as it will be permanently deleted. - addTopLevelItem(item): A top-level item can be added to
the QTreeWidget object using this method. The
QTreeWidgetItem or one of its subclass can be the item
parameter. - currentItem(): The current item in the QTreeWidget object
(the one that is selected and has focus) is returned by
this method. - selectedItems(): This method will return a list of all
selected non-hidden items in the QTreeWidget object. - setHeaderLabels(labels): This method is used to set the
header labels list of strings for each column of the
QTreeWidget object. - sortItems(column,order): This function uses the specified
column and orders to sort the items in the QTreeWidget object. The order parameter is a Qt.SortOrderenum
Qt.AscendingOrder or Qt.DescendingOrder and the column
parameter is an integer that specifies the column to
sort by. - takeTopLevelItem(index): This method is used to remove an
item from the QTreeWidget object at the specified index
parameter and return it. Otherwise, it will return None.
The index parameter is the index of the item to be
removed. - setColumnCount(columns): The number of columns displayed.
Important Signals
- itemActivated(item,column): When an item is activated
double-clicked or pressed when the Enter key is
pressed, this signal is emitted. The item parameter is
the activated item and the column parameter is the
column of the item. - itemChanged(item,column): When an item’s data has been
changed, this signal is emitted. The item parameter is
the changed item and the column parameter is the
column of the item. - itemClicked(item,column): When an item is clicked, this
signal is emitted. The item parameter is the clicked
item and the column parameter is the column of the
item. - itemCollapsed(item): When an item is collapsed its
children are hidden, this signal is emitted. The item
parameter is the collapsed item. - itemDoubleClicked(item,column): When an item is double
clicked, this signal is emitted. The item parameter is the double clicked item and the column parameter is
the column of the item. - itemEntered(item,column): When the mouse-cursor enters
an item, this signal is emitted. The item parameter is
the entered item and the column parameter is the
column of the item. - itemExpanded(item): This signal is emitted when an item is
expanded its children are shown. The item parameter
is the expanded item. - itemPressed(item,column): When an item is pressed, this
signal is emitted. The item parameter is the pressed
item and the column parameter is the column of the
item.
Now, we shall see an example of QTreeWidget.
Consider the following code of run_treeWidget_eg1.py:
import sys
from PyQt5.QtWidgets import QMainWindow,
QApplication, QTreeWidget, QTreeWidgetItem
from PyQt5.QtGui import QPalette, QColor
from treeWidget_eg1 import *
class MyTreeWidget(QMainWindow):
def __init__(self):
super().__init__()
self.myui = Ui_MainWindow()
self.myui.setupUi(self)
# Initially setting the column count of the
treeWidget object to 2
self.myui.treeWidget.setColumnCount(2)
# Set the header labels for 2 columns
self.myui.treeWidget.setHeaderLabels(["Name","Age"])
# Adding items to the treeWidget object
myitem1 = QTreeWidgetItem(["Saurabh", "34"])
myitem2 = QTreeWidgetItem(["Nilesh", "42"])
myitem3 = QTreeWidgetItem(["Priyanka", "30"])
myitem4 = QTreeWidgetItem(["Pranav", "31"])
myitem5 = QTreeWidgetItem(["Papa", "61"])
myitem6 = QTreeWidgetItem(["Mummy", "60"])
# For TreeWidget1
self.myui.treeWidget.addTopLevelItem(myitem1)
self.myui.treeWidget.addTopLevelItem(myitem2)
self.myui.treeWidget.addTopLevelItem(myitem3)
self.myui.treeWidget.addTopLevelItem(myitem4)
self.myui.treeWidget.addTopLevelItem(myitem5)
self.myui.treeWidget.addTopLevelItem(myitem6)
# Connecting the itemClicked signal to the
handle_item_click method
self.myui.treeWidget.itemClicked.connect(self.myhan
dle_item_click)
# Connecting the itemDoubleClicked signal
to the handle_item_double_click method
self.myui.treeWidget.itemDoubleClicked.connect(self
.myhandle_item_double_click)
# Connecting the itemActivated signal to
the handle_item_activation method
self.myui.treeWidget.itemActivated.connect(self.myh
andle_item_activation)
# For TreeWidget2
# Setting the column count to 1
self.myui.treeWidget_2.setColumnCount(1)
# Create the top-level items
self.myitemA =
QTreeWidgetItem(self.myui.treeWidget_2, ["Item A"])
self.myitemB =
QTreeWidgetItem(self.myui.treeWidget_2, ["Item B"])
self.myitemC =
QTreeWidgetItem(self.myui.treeWidget_2, ["Item C"])
# Create the child items for Item A
self.myitemA1 =
QTreeWidgetItem(self.myitemA, ["Item A_1"])
self.myitemA2 =
QTreeWidgetItem(self.myitemA, ["Item A_2"])
# Create the child items for Item B
self.myitemB1 =
QTreeWidgetItem(self.myitemB, ["Item B_1"])
self.myitemB2 =
QTreeWidgetItem(self.myitemB, ["Item B_2"])
# Create the child items for Item C
self.myitemC1 =
QTreeWidgetItem(self.myitemC, ["Item C_1"])
self.myitemC2 =
QTreeWidgetItem(self.myitemC, ["Item C_2"])
# Connect the itemExpanded and
itemCollapsed signals to their respective slots
self.myui.treeWidget_2.itemExpanded.connect(self.my
_on_item_expanded)
self.myui.treeWidget_2.itemCollapsed.connect(self.m
y_on_item_collapsed)
self.show()
# Method to handle item click event
def myhandle_item_click(self,item, column):
print("An Item is clicked:",
item.text(column))
# Method to handle item double click event
def myhandle_item_double_click(self,item,
column):
print("An Item is double clicked:",
item.text(column))
# Method to handle item activation event
def myhandle_item_activation(self,item, column):
print("An Item is activated:",
item.text(column))
def my_on_item_expanded(self, item):
# Performing some action when an item is expanded
print(f"{item.text(0)} was expanded")
def my_on_item_collapsed(self, item):
# Performing some action when an item is collapsed
print(f"{item.text(0)} was collapsed")
if __name__=="__main__":
app = QApplication(sys.argv)
w = MyTreeWidget()
w.show()
sys.exit(app.exec_())
Output:
Case 1 — Output display when performing Item clicked
event on Name = Saurabh
Case 2 — Output display when performing Item double-
clicked event on Name = Nilesh
Here, on pressing double-clicked event on Name = Nilesh, the
first clicked event is triggered followed by double clicked
event and then the activated event.
Case 3 — Output display when performing Item
Activated event on Name = Priyanka
Here , Enter key is pressed when the control is on Name =
Priyanka. That is why the initially clicked event is triggered
along with the activated event on pressing Enter key.
Case 4 — Output display when performing Item Expanded event
Here, Item A, Item B and Item C was expanded triggering
expanded event.
Case 5 — Output display when performing Item Collapsed event
Here, Item A, Item B and Item C was collapsed triggering
collapsed event.
Table Widget
A widget called QTableWidget in PyQt5 displays data in a table
format with rows and columns. It supports several types of
data like text, icons, and checkboxes and allows for data
manipulation such as sorting and editing. Additionally, it can
be used to display information from a model or database. It is comparable to QTableView but offers more efficient data handling techniques. QTableWidgetItem provides the items for a
QTableWidget.
Important Properties
The properties of QTableWidget are similar to the QTableView
properties seen in the previous chapter. Apart from these properties, the only other 2 properties which are added are
as follows.
rowCount
This property will return the number of rows in the
QTableWidget object. We can set the number of rows by passing
an integer value to this property. The default value is set to
0.
Designer
Column count
This property will return the number of columns in the
QTableWidget object. We can set the number of columns by
passing an integer value to this property. The default value is
set to 0.
Designer
Important Methods
- setItem(int row, int column, QTableWidgetItem): This method
will set the item at a specified row and column position
in the QTableWidget object. The item may be an object of
the class QTableWidgetItem or one of its subclasses. - item(int row, int column): The item is returned as a
QTableWidget object at a specified row and column
position if set otherwise returns None. - setCellWidget(int row, int column, QWidget): This method
sets a widget that is to be displayed in the cell at a
specified row and column position in the QTableWidget
object. This can be useful to display data types such as
a push button or a checkbox. - cellWidget(int row, int column): This method returns a
widget as a QWidget object at a specified row and column
position in the QTableWidgetItem object. - removeRow(int row): This method will remove a row from
the QTableWidget object where the row number is passed
as an argument. - removeColumn(int column): This method will remove a
column from the QTableWidget object where the column
number is passed as an argument. - sortItems(int column[,order=Qt.AscendingOrder]): This method
sorts the rows in the QTableWidget object based on the
values in a specified column where the column number
and the sort order ascending or descending are
passed as arguments. - clear(): Using this method, all the items and widgets
are removed from the QTableWidget object.
Important Signals
- itemSelectionChanged(): The signal is emitted when the
selection in the QTableWidget object is changed. - cellClicked(row,column): The signal is emitted when the
cell in the QTableWidget object is clicked and takes the
row and column of the clicked cell as arguments. - cellDoubleClicked(row,column): The signal is emitted when
the cell in the QTableWidget object is double-clicked and
takes the row and column of the double-clicked cell as
arguments. - cellChanged(row,column): The signal is emitted when the
cell in the QTableWidget object is changed and takes the
row and column of the changed cell as arguments. - cellEntered(row,column): The signal is emitted when the
user enters a cell in the QTableWidget object and takes the
row and column of the entered cell as arguments. The
cellEntered signal is only triggered when the QTableWidget
object has the focus, which occurs when the user clicks
inside or tabs to the object. - cellPressed(row,column): The signal is emitted when the
user presses a cell in the QTableWidget object and takes
the row and column as arguments.
Now, we shall see an example of QTableWidget.
Consider the following code of run_tableWidget_eg1.py:
import sys
from PyQt5.QtWidgets import QMainWindow,
QApplication,QTableWidgetItem,QHeaderView
from PyQt5.QtGui import QPalette, QColor
from tableWidget_eg1 import *
class MyTableWidget(QMainWindow):
def __init__(self):
super().__init__()
self.myui = Ui_MainWindow()
self.myui.setupUi(self)
# Seting the number of rows and columns of
QTableWidget object
self.myui.tableWidget.setRowCount(2)
self.myui.tableWidget.setColumnCount(3)
# Set the horizontal headers for the table
self.myui.tableWidget.setHorizontalHeaderLabels(["N
ame", "Age", "Sex"])
# Adding some data to the QTableWidget object
self.myui.tableWidget.setItem(0,0,QTableWidgetItem("Saurabh"))
self.myui.tableWidget.setItem(0,1,QTableWidgetItem("34"))
self.myui.tableWidget.setItem(0,2,QTableWidgetItem("Male"))
self.myui.tableWidget.setItem(1,0,QTableWidgetItem("Aditi"))
self.myui.tableWidget.setItem(1,1,QTableWidgetItem("30"))
self.myui.tableWidget.setItem(1,2,QTableWidgetItem("Female"))
#for fitting the QTableWidget object horizontally
self.myui.tableWidget.horizontalHeader().setStretch
LastSection(True)
self.myui.tableWidget.horizontalHeader().setSection
ResizeMode(QHeaderView.Stretch)
# connect signals to slots
self.myui.tableWidget.cellChanged.connect(self.myce
llChanged)
self.myui.tableWidget.cellClicked.connect(self.myce
llClicked)
self.myui.tableWidget.cellEntered.connect(self.mycellEntered)
self.myui.tableWidget.cellPressed.connect(self.myce
llPressed)
# clicked signal of button connecting to slot btn_click
self.myui.btn_Add.clicked.connect(self.btn_click)
self.show()
# defining the slots
def mycellChanged(self, myrow, mycol):
print("Cell is changed at row {0}, col
{1}".format(myrow, mycol))
def mycellClicked(self, myrow, mycol):
print("Cell is clicked at row {0}, col
{1}".format(myrow, mycol))
def mycellEntered(self, myrow, mycol):
print("Cell is entered at row {0}, col
{1}".format(myrow, mycol))
def mycellPressed(self, myrow, mycol):
print("Cell is pressed at row {0}, col
{1}".format(myrow, mycol))
def btn_click(self):
# inserting a new row at the end of the
QTableWidget object by taking rowCount
myrow = self.myui.tableWidget.rowCount()
self.myui.tableWidget.insertRow(myrow)
# adding fixed name, age and sex to display
to the user of inserting new data
self.myui.tableWidget.setItem(myrow, 0,
QTableWidgetItem("Divya"))
self.myui.tableWidget.setItem(myrow, 1,
QTableWidgetItem("36"))
self.myui.tableWidget.setItem(myrow, 2,
QTableWidgetItem("Male"))
if __name__=="__main__":
app = QApplication(sys.argv)
w = MyTableWidget()
w.show()
sys.exit(app.exec_())
Output:
Case 1 — When Add button is clicked on QTableWidget object
When new data is added in the row of the QTableWidget object then the cellChanged event is triggered.
Case 2 — When a cell is clicked or pressed on the QTableWidget object
When a cell with data row number as 2 and column number
as 0 is clicked, then first cellPressed and then the cellClicked
event is triggered.
Case 3 — When a cell is changed on the QTableWidget object
When we are trying to change the data of row number 2 and
column number 0 and after changing when pressing Enter
button, the cellChanged event is triggered.
Case 4 — When a cell is entered on the QTableWidget object
When the user enters a cell with row number 2 and columns
0 and 1 then the cellEntered event is triggered.
Conclusion
In this section, we will learned about in-depth understanding of
Item Widgets, including QListWidget, QTreeWidget and QTableWidget
which allows for creation of dynamic user interfaces. This
section has provided a comprehensive understanding of Item Widgets in Qt Designer which are essential for creating
interactive user interfaces. By delving into their properties,
functionality, customization options and operational
techniques within the Qt Designer environment, readers
have gained the necessary knowledge to create and utilize
item based widgets effectively. Additionally, users have
learned how to manage events and signals connected to
item based widgets to facilitate user interaction and
implement desired functionality. Users will be well prepared
to develop a complex yet user friendly interface in Qt
Designer using item based widgets. The inclusion of solved
examples with explanatory comments throughout the
section has further enhanced the understanding and
application of item widget.