8. List Widgets

Qt provides several widgets for displaying and managing lists of items, including:

  • QComboBox - for showing a compact dropdown list,
  • QTableWidget- for built-in list item management,
  • QTableView - for model-based list mnagement.

8.1 QComboBox

QComboBox combines a button and a line edit with a pop-up list, which makes it useful for displaying list in a constrained space. It can be populated using its insert methods:

  • addItem() - appends an item,
  • addItems() - appends a list of items,
  • insertItem() - insert an item at the given index,
  • insertItems() - inserts a list of items at the given index,
  • removeItem() - removes the item at the given index.

Combobox items can have text, icons, and additional user data. As QCombobox is a part of the Qt’s model/view framework, you can provide data for it using one of the Qt model classes instead of managing items manually.

QComboBox provides several signals:

Signal Description
activated(index) User chooses an item from the list
currentIndexChanged(index) Current index changes (user or programmatic)
currentTextChanged(text) Current text changes
editTextChanged(text) Text edited in editable combobox
highlighted(index) Item in the popup list highlighted
textActivated(text) User chooses an item
textHighlighted(text) Item in the popup list highlighted

Combobox items are indexed, starting from zero. Its line edit widget can be accessed with QComboBox.lineEdit() and it can be made editable with setEditable().

An icon of a clipboard-list1

You need to enable the user to select an economic sector from the list and also add new sectors to the list. When a sector is selected, all other users need to be notified. To do this:

 1 # The QComboBox widget is a combined button and popup list.
 2 
 3 import sys
 4 from PySide6.QtCore import Slot
 5 from PySide6.QtWidgets import (QApplication,
 6     QWidget, QVBoxLayout, QComboBox, QLabel)
 7 
 8 
 9 class Window(QWidget):
10     
11     def __init__(self):
12 
13         super().__init__()
14         
15         layout = QVBoxLayout()
16         self.setLayout(layout)
17         
18         # 1. Create the combo box and add items to it
19         
20         self.combo_box = QComboBox()
21         
22         self.combo_box.addItems([
23             'Technology',
24             'Healthcare',
25             'Finance',
26             'Energy',
27             'Real Estate'])
28         
29         # 2. Enable the user to add items
30         
31         self.combo_box.model().sort(0)
32         self.combo_box.setCurrentIndex(1)
33         self.combo_box.setEditable(True)
34         self.combo_box.setInsertPolicy(
35             QComboBox.InsertPolicy.InsertAlphabetically)
36 
37         self.label_activated = QLabel()
38 
39         layout.addWidget(self.combo_box)
40         layout.addWidget(self.label_activated)
41 
42         self.combo_box.activated.connect(self.on_activated)
43     
44     # 3. Create the slot
45     
46     @Slot(int)
47     def on_activated(self, index):
48         item_text = self.combo_box.currentText()
49         self.label_activated.setText(f'Selected: {item_text}')
50 
51 
52 if __name__ == '__main__':
53 
54     app = QApplication(sys.argv)
55     main_window = Window()
56     main_window.show()
57     sys.exit(app.exec())
  1. Create a QComboBox object and add items to it. Sort the combobox items and set the first item as the current item.

  2. Enable the user to add items. QComboBoxes are read-only by default so set the editable() property to True. Set the added items to be inserted alphabetically.

  3. Create a slot to notify users when an item is selected. Connect to the list widget’s activated() signal. When the user selects an item or adds a new one to the list, the slot is executed.

8.2 QListWidget

The QlistWidget class is an item-based list widget. This means its items are instances of the QListWidgetItem class, and you add them to the list widget using methods such as:

  • addItem(item),
  • addItem(label) or
  • addItems(labels).

QListWidget also provides methods to insert items at specific positions, retrieve an item at a given row, and remove an item using the takeItem(row) method.

QListWidgetItem, the accompanying class, can hold several pieces of information, such as text, icons, or tooltips. It can also store custom user-defined data.

Common QListWidgets include:

Signal Description
currentItemChanged(current, previous) Emitted when the current item changes.
currentRowChanged(currentRow) Emitted when the current row changes.
currentTextChanged(currentText) Emitted when the text of the current item changes.
itemActivated(item) Emitted when an item is activated (double-click or Enter/Space while selected).
itemChanged(item) Emitted when an item’s data is modified by the user.
itemClicked(item) Emitted on any mouse click on an item.
itemDoubleClicked(item) Emitted specifically on double-click.
itemSelectionChanged() Emitted when the selection changes.
An icon of a clipboard-list1

You need to create a list of common weather conditions. When the user selects one, you need provide additional information about it. To do this:

 1 # The QListWidget class provides
 2 # an item-based list widget
 3 
 4 import sys
 5 from PySide6.QtCore import Slot, Qt
 6 from PySide6.QtWidgets import (QApplication,
 7     QWidget, QVBoxLayout, QListWidget, QLabel,
 8     QListWidgetItem)
 9 
10 
11 class Window(QWidget):
12     
13     def __init__(self):
14 
15         super().__init__()
16         
17         layout = QVBoxLayout()
18         self.setLayout(layout)
19         
20         weather_conditions = [
21             ('☀️ Clear', 'Sunny skies with no cloud coverage'),
22             ('⛅ Partly Cloudy', 'Sun and clouds throughout the day'),
23             ('☁️ Cloudy', 'Overcast skies with full cloud coverage'),
24             ('🌧️ Rain', 'Precipitation with steady rainfall'),
25             ('⛈️ Thunderstorm', 'Heavy rain with lightning and thunder'),
26             ('❄️ Snow', 'Frozen precipitation and cold temperatures')
27         ]
28         
29         # 1. Create a list widget and add items to it.
30         
31         self.weather_list = QListWidget()
32         
33         for name, description in weather_conditions:
34             item = QListWidgetItem(name)
35             item.setData(Qt.ItemDataRole.UserRole, description)
36             self.weather_list.addItem(item)
37 
38         self.selected_label = QLabel()
39         self.description_label = QLabel()
40         self.selected_label.setStyleSheet("font-size: 24px;")
41         
42         layout.addWidget(self.weather_list)
43         layout.addWidget(self.selected_label)
44         layout.addWidget(self.description_label)
45         
46         # 3. Connect the signal to the slot.
47 
48         self.weather_list.currentItemChanged.connect(
49             self.select_weather)
50         self.weather_list.setCurrentRow(0)
51     
52     # 3. Create the slot.
53     
54     @Slot(QListWidgetItem, QListWidgetItem)
55     def select_weather(self, current, previous):
56 
57         weather = current.data(Qt.ItemDataRole.DisplayRole)
58         description = current.data(Qt.ItemDataRole.UserRole)
59         self.selected_label.setText(weather)
60         self.description_label.setText(description)
61 
62 
63 if __name__ == '__main__':
64 
65     app = QApplication(sys.argv)
66     main_window = Window()
67     main_window.show()
68     sys.exit(app.exec())
  1. Create a QListWidget object and add items to it. After creating the list widget, create a Python list of tuples, where each tuple’s first element contains the weather condition name and the second element contains its description. Iterate over the list, and for each tuple, create a QListWidget object, setting the weather condition description as custom user data. Add each widget item to the list widget. Also create two labels for displaying the information.

  2. Implement a slot to display the weather condition name and description when the current item is changed. You get the name of a weather condition using the DisplayRole item data role, and the description using the UserRole item data role.

  3. Connect the signal to the slot. The currentItemChanged() signal is emitted whenever the current item changes. It provides both the current and the previous QListWidgetItem objects to the slot (though we need only the current item in this example).

8.3 QListView

A QListView presents items stored in a model, either as a list or a collection of icons. It is part of Qt’s model/view framework, which separates data (models) from its visual representation (views). This allows one model to be shared across multiple views.

An icon of a clipboard-list1

Provide a read-only list view of the user’s home directory, decorating each item with an appropriate icon. When the user hovers over a file, display a tooltip showing its size in KB. To do this:

 1 # QListView presents items stored in a model.
 2 # ie. it uses the QT model/view architecture
 3 # Models contain data and views display it
 4 # so one model can be used with multiple views.
 5 
 6 import sys
 7 from pathlib import Path
 8 from PySide6.QtCore import Qt
 9 from PySide6.QtGui import QStandardItemModel, QStandardItem
10 from PySide6.QtWidgets import (QApplication, QWidget,
11     QVBoxLayout, QListView, QAbstractItemView, QStyle)
12 
13 
14 class Window(QWidget):
15     
16     def __init__(self, parent=None):
17 
18         super().__init__(parent)
19         
20         layout = QVBoxLayout()
21         self.setLayout(layout)
22         
23         # 1. Create the view
24         
25         self.list_view = QListView()
26         self.list_view.setEditTriggers(
27             QAbstractItemView.EditTrigger.NoEditTriggers)
28         
29         # 2. Create the model and populate it with data
30         
31         self.model = QStandardItemModel()
32         
33         home = Path.home()
34         fs_entries = home.iterdir()
35 
36         for entry in fs_entries:
37             item = QStandardItem(entry.name)
38             icon = self.get_icon(entry)
39             item.setIcon(icon)
40             tooltip = self.get_tooltip_data(entry)
41             item.setData(tooltip, Qt.ItemDataRole.ToolTipRole)
42             self.model.appendRow(item)
43         
44         # 3. Set the view's model
45         
46         self.list_view.setModel(self.model)
47         
48         layout.addWidget(self.list_view)
49         
50     def get_icon(self, path):
51         if path.is_dir():
52             return self.style().standardIcon(
53                 QStyle.StandardPixmap.SP_DirIcon)
54         else:
55             return self.style().standardIcon(
56                 QStyle.StandardPixmap.SP_FileIcon)
57             
58     def get_tooltip_data(self, path):
59         if path.is_dir():
60             return 'Directory'
61         elif path.is_file():
62             size = round(path.stat().st_size / 1024, 2)
63             return f'File: {size} KB'
64         else:
65             return 'File System Entry'
66 
67 
68 if __name__ == '__main__':
69 
70     app = QApplication(sys.argv)
71     main_window = Window()
72     main_window.show()
73     sys.exit(app.exec())
  1. Create the view. Instantiate a QListView object and disable its edit triggers using NoEditTriggers - this prevents actions like double-click editing.

  2. Create the model and populate it with data. Use a QStandardItemModel object to store filesystem data. For each filesystem entry in the user’s home directory create a QStandardItem object, initialize it with the entry name, and set its icon based on the type (file or directory). If the entry is a file, set its tooltip text to the file size in a human-readable format. Finally, append the item to the model.

  3. Set the view’s model to the QStandardItemModel object.

We use Python’s pathlib.Path to access filesystem data for the model. In the get_icon() method, we return the Qt’s standard icons for files and directories to avoid using external resources. When initializing a QStandardItem with a filesystem entry name, the name is assigned to the DisplayRole by default. To assign data to its tooltip, use the ToolTipRole when setting the data.